home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1995-12-30 | 1.0 MB | 33,705 lines | [ TEXT/R*ch]
Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
Master Bug List, Standard ML of New Jersey as of June 26, 1991. Most of these bugs have been fixed; these are all bugs ever reported. ------------------------------------------------------------------------------- 1. Identifier as functor body (dbm) Problem: Using a parameter structure variable as the body of a functor yields an error message. Code: functor F(structure A: sig end) = A Messages: Error: unbound structure id: A Comment: Status: fixed in 0.20, along with some related bugs involving lack of visibility of parameters on the rhs of functor declarations. ------------------------------------------------------------------------------- 2. Mispelled nonnullary constructors in patterns Problem: Mispelling a constructor with arguments in a pattern leads to misleading error messages. Version: 0.18 Code: (in typing/typecheck.sml) ... app genType rvbs end | EXCEPTIONdec(ebs) => let fun checkWeak(VARty(ref(UNBOUND id))) = if tyvarWeakness id > abs then condemn "type variable in exception type too strong" ... Status: Fixed in 0.50 ------------------------------------------------------------------------------- 3. Redefining an open structure at top level Problem: It appears that redeclaration of an opened structure S releases the runtime binding of S, even though we can still refer to its component x. We get the effect of a kind of dangling reference. Need to avoid reclaiming S if S is open at the point where it is redeclared. Version: 0.18 Code: - structure S = struct datatype t = A val x = A end; structure S : <sig> - S.x; val it = A : S.t - open S; open S - x; val it = A : t - type t = bool; type t = bool - x; val it = A : S.t - structure S = struct end; structure S : <sig> - x; uncaught exception Intmap - Comment: Need to detect the fact that a structure has been opened at the top level and if so it's lvar binding should not be deleted from the top-level environment. Status: fixed in 0.20. top level opens copy bindings into top level environment. -------------------------------------------------------------------------------- 4. duplicate specifications not checked Problem: No checking for duplicated specifications in signatures. Version: 0.18 Comment: This should be done when building the signature symbol table. See bug 81. (elg) Status: fixed in 0.73 -------------------------------------------------------------------------------- 5. exportML environment Problem: Subtle bug in exportML: it exports the environment of the person who originally booted the system, and this environment is restored when the image is started up. This effects system, execute, and subsequent exportML's. On startup, exportFN destroys the environment and command-line args, and this too could have adverse effects on those functions. Version: 0.18 Status: fixed in version 0.31 -------------------------------------------------------------------------------- 6. open file descriptors Problem: File descriptors open in the ML system remain open on a call of system. Version: 0.18 Comment: I haven't decided what I want to do about this yet. We might like only stdin, stdout, and stderr to remain open. Note that if the parent closes one of them, it will be closed in the child as well (it inherits them rather than getting new ones). Note that ioctl(fd,FIOCLEX,(void *)0) will cause a file descriptor to be closed on an exec. This could be called after each open (but shouldn't be called on pipes). Another possibility is just to leave them all open. Status: not a bug, reflects Unix semantics -------------------------------------------------------------------------------- 7. constructor representation Problem: There is a bug involving constructor representation. The compiler examines the structure of a datatype and tries to determine an efficient runtime representation for it. For example, for the list datatype, nil can be represented as an integer, and :: can just be a pointer to its tuple argument (integers and tuples are distinct). This fails in our system at the structure level. For example: Version: 0.18 Code: signature S = sig type 'a t datatype 'a list = nil | :: of 'a t end structure A : S = struct datatype 'a list = nil | :: of 'a * 'a list withtype 'a t = 'a * 'a list end Comment: Here the compiler can deduce the efficient representation for the (local) list datatype in structure A; but this cannot be deduced in the signature S (an object of type 'a t might not be a pointer). Status: An error message is now generated (0.54) when this occurs. -------------------------------------------------------------------------------- 8. interactive error recovery Problem: In the interactive mode, parser error recovery should be suppressed (but isn't); the parser may continue to look for input after an error, when the user would expect to be back at top level. Version: 0.18 Status: Fixed in 0.52 -------------------------------------------------------------------------------- 9. behavior at limits (e.g. stack overflow) Problem: The behavior of the system when it reaches limits is sometimes bizarre. For instance, on a Sun, if the system runs out of stack space it will die with "Illegal instruction". This is because the signal can't be handled since the stack is full. A possible fix would be to use a separate stack to handle signals, but the handler would have to be smart, since SIGSEGV would be raised. Note that the stack limit can be changed with the limit command; and hopefully this particular bug will disappear with the next version of the code generator. Version: 0.18 Status: fixed in version 0.31 -------------------------------------------------------------------------------- 10. exhaustiveness messages at top-level Problem: Top level bindings should not report on exhaustiveness, but they do. Version: 0.18 Status: Not important. -------------------------------------------------------------------------------- 11. poor error messages [parser] Problem: Poor error message (parens are needed around the hd::tl pattern): Version: 0.18 Code: - fun f hd::tl = 4; Messages: Error: expected EQUAL, found ID (::) Error: expected nonfix-identifier, found ID :: Error: unbound variable bogus Error: type error: operator and operand don't agree operator : ((wrong*wrong list) -> wrong list) operand : (wrong*('aA list -> 'aA list)) expression: bogus :: tl - Comment: The "unbound variable bogus" in particular is confusing. Status: Fixed in 0.52. ----------------------------------------------------------------------------- 12. loss of information in value printing Problem: When printing values formed using constructors created by functor application, the argument type of the constructor can sometimes be lost, resulting in inability to print the value accurately. Version: 0.18 Code: - functor F(type t) = = struct = datatype r = C of t = end; - structure S = F(type t = int); - S.C 3; [1] val it = C - : S.r But - signature SS = sig type t datatype r = C of t end; - structure S = struct type t = int datatype r = C of t end; - S.C; val it = fn : ?.t -> S.r - S.C 3; val it = C 3 : S.r and - structure S': SS = struct type t = int datatype r = C of t end; - S'.C; val it = fn : ?.t -> S'.r - S'.C 3; val it = C 3 : S'.r Comments: Printing the argument type of C at [1] yields "IND/1/", indicating that the type of C contains an indirection that is not interpreted in context. It does not seem possible to recover the context from the structure S, because there is no simple way to get back from the type S.r or the DATACON C to the structure environment. This may be a reason for having type constructors contain a pointer to their home structure rather than just the symbolic path. Another alternative would be to follow the path in S.r to find the structure S so that we can use it as context for the type of C. Status: fixed in 0.58 ----------------------------------------------------------------------------- 13. printing of types from abstraction structure Problem: Printing of types from an abstraction is not quite right. Code: (test/sigs/test7) signature FOO = sig type T1 and T2 val x1: T1 and x2: T2 sharing type T1 = T2 end abstraction Foo: FOO = struct datatype T1 = CON type T2 = T1 val x1 = CON and x2 = CON end [Foo.x1,Foo.x2]; Messages: [-,-] : ?.T1 (* should be Foo.T1 *) Status: Fixed in 0.56 -------------------------------------------------------------------------------- 14. Bad printing of list values Problem: list values printed with :: instead of [...] Version: Code: datatype Foo = FOO of int list val it = FOO [1, 2, 3] Messages: FOO (1 :: 2 :: 3 :: nil): Foo Comments: Status: Fixed in version 0.25. -------------------------------------------------------------------------------- 15. Error message Problem: Unfortunate error message (I left out `type'): Version: ? Code: - signature STWO = sig structure X:SIG and Y:SIG sharing X.t=Y.t end; Messages: Error: bad path is sharing specification Comments: (It's also misspelled.) Status: fixed in 0.56 -------------------------------------------------------------------------------- 16. "use" errors Problem: Untidy interface to "use". "use" on a nonexistent file still prints the "[opening ...]" message and then raises Io_failure - shouldn't it just say "[cannot open ...]" or something? Status: fixed -------------------------------------------------------------------------------- 17. Inaccurate line numbers Problem: Misleading line numbers for some things (eg. type errors in multi-line datatype declarations). Could the system print something like "Line 33ff", or a line range a la LaTeX, for these? Status: fixed in 0.53 -------------------------------------------------------------------------------- 18. Bad error messages for illegal record expression Version: [< 0.16] Problem: interesting diagnostic in the (meaningless) expression Code: - {3}; Messages: Error: expected RBRACE, found INT Error: type error: operator and operand don't agree operator : unit operand : int expression: () 3 Error: declaration or expression expected, found RBRACE Comment: What's the "() 3"? Status: fixed in 0.53 -------------------------------------------------------------------------------- 19. Exception declaration with ":" Problem: This gives a type error rather than a syntax error: odd: Version: ? Code: - signature FOO = sig exception Foo of string end; - structure Foo: FOO = struct exception Foo: string end; =-> ^ <-= Messages: Error: Type in structure doesn't match signature name = Foo spec = (string -> exn) actual = exn Comments: Without signature constraint ":FOO" in declaration of Foo you get a syntax error: "expected END, found COLON". With the signature, you get the above type error but no complaint about the ":". Status: fixed in 0.53 -------------------------------------------------------------------------------- 20. "print" seems overloaded rather than polymorphic: Problem: print is overloaded rather than being polymorphic Version: - Code: - datatype Foo = FOO1 | FOO2; - print FOO1; Messages: Error: type error: no match for overloaded variable: print Comments: according to the original SML report, both "print" and "makestring" should be polymorphic identity functions. In our compiler, "print" is correctly polymorphic. "makestring" is (incorrectly) overloaded, disallowing "makestring FOO1". Needless to say, I want to be able to do "makestring" on datatypes. Status: not a bug -------------------------------------------------------------------------------- 21. Bad error recovery in the typechecker: Problem: Version: 0.15a Code: - signature SIG = sig exception Foo of int val A: int val B: int val C: int end; - structure S: SIG = struct exception Foo: int ^ val A = 1 val B = 2 val C = 3 end Messages: Error: Type in structure doesn't match signature name = Foo spec = (int -> exn) actual = exn Error: unmatched val spec: A Error: unmatched val spec: B Error: unmatched val spec: C ^ there can be a lot of these! Comments: Sometimes the exception error doesn't appear, just giving the unmatched spec errors, rather misleadingly. Status: fixed in 0.53 -------------------------------------------------------------------------------- 22. inherited environment of subprocesses Problem: (one you know about) - subprocesses created via "execute" inherit the environment present when the ML system was built! Also: broken pipe errors should be caught and raise Io_failure? Status: fixed in 0.31 -------------------------------------------------------------------------------- 23. circularity in substructure relationship Problem: No checking for circular sharing constraints. Circular constraints cause unhandled Notfound_Table exception. Code: - signature Sig = sig structure D: sig structure E: sig end end sharing D = D.E end; Messages: uncaught exception Notfound_Table Comments: By the way - why is "sharing structure D = D.E" illegal above? (it dislikes the word "structure".) See bug 33. (elg) Status: Not considered a bug (signature can't be matched, -- this property could be statically detected in the compiler, but isn't). -------------------------------------------------------------------------------- 24. incomplete write Submitter: Nick Comments: I'm trying to put in some bullet-proof error recovery into my subprocess software, so that "^C" at ML top-level doesn't confuse the daemon. What happens if an "output" operation is active when ^C is hit - does it do a partial write? I seem to be getting some buffer corruption somewhere, as a partial write is immediately followed by another complete write. It might make my life easier if "output" could be guaranteed atomic under "^C" (i.e. any single output operation will complete before Interrupt gets raised). Just a thought. I'll perhaps put timers into the daemon and ML code so that they flush and restart properly - this may solve the problem. Status: New signal-handling stuff in 0.56 makes this less important. -------------------------------------------------------------------------------- 25. parser vs grammar (?) Problem: Parser doesn't accept "vb ::= rec rec vb". Status: language problem -------------------------------------------------------------------------------- 26. export ML within a use Problem: Awkward behaviour when exportML is called while a file is being "use"'d - the saved state falls over with Io_failure. Shouldn't restarting clear the use stack?Version: Status: Modified in version 18 so the image doesn't die. It still raises Io_failure, though. (tyj) Fixed in 0.56 -------------------------------------------------------------------------------- 27. different numbers of arguments in curried clauses cause bogus type error Version: 0.15 Code: fun compose [] = (fn x => x) | compose (f::fl) x = compose fl (f x); Messages: Error: type error: rules don't agree expected: ('a list -> ('b -> 'b)) found: (f :: fl,x) => compose fl (f x) : ((('c -> 'd) list*'c) -> 'e) Status: fixed in 0.19. -------------------------------------------------------------------------------- 28. tyvars in top-level type constraint Submitter: Carl Gunter, gunter@linc.cis.upenn.edu (also Reppy, 4/20/88) Date: 3/27/88 Version: 0.18 Problem: tyvars not accepted in top-level type constraint Code: - length : 'a list -> int; Messages: (compiler messages associated with bug) Error: lookTyvar -- unbound tyvar in closed scope Error: Impossible error: generalizeTy -- bad arg undef list -> int Status: fixed in 0.20 (put protectTyvars around top level expression parse). -------------------------------------------------------------------------------- 29. use_string in structure definition Submitter: Nick Date: 3/24/88 Version: 0.18 Problem: use_string can cause uncaught Intmap exception Code: - structure Foo = struct val x = use_stream(open_string "val _ = Foo.x;") end; Messages: [opening <instream>] [closing <instream>] uncaught exception Intmap Comments: This code shouldn't work, but the Intmap exception should be caught. Status: Fixed in 0.54 -------------------------------------------------------------------------------- 30. weakness 0 in constraint Date: 4/5/88 Version: 0.18 Problem: Code: - fn (x: '0a) => x; Messages: Error: lookTyvar -- inbound tyvar in closed scope Error: Impossible error: generalizeTy -- bad arg undef -> undef Comments: Weak-tyvars of level 0 should raise an error when they occur in constraints. Status: fixed (indirectly) in 0.20. causes error Error: can't generalize weak type variable '0a -> '0a -------------------------------------------------------------------------------- 31. redefining an open structure orphans r/t bindings Submitter: John Reppy, jhr@svax.cs.cornell.edu Date: 4/4/88 Version: 0.18 Problem: Redefining a structure after opening it makes its components inaccessible at runtime even though they are still visible, because the structure binding is removed from the r/t intmap environment. Code: val it = () : unit - structure S = struct type t = int; val x = 1 end; structure S : <sig> - open S; open S - structure S = struct type t = bool; val x = true end; structure S : <sig> - x; Messages: uncaught exception Intmap Comments: can't eliminate a structure from r/t env if it has been opened See bug 1. (elg) Status: fixed -------------------------------------------------------------------------------- 32. printing loops Submitter: Andrew Date: 4/6/88 Version: 0.18 Problem: printing a cyclic data structure involving a ref loops Code: datatype A = B | C of A ref val x = C(ref B); val C y = x; y := x; x; Messages: prints endlessly Comments: probably not handling ref constructors properly in tracking depth Status: fixed in 0.20. missing base (depth = 0) in printDcon in printval.sml. -------------------------------------------------------------------------------- 33. cyclical sharing not checked, parsing problem Submitter: Mads Date: 4/12/88 Version: 0.18 Problem: cyclical sharing not detected, but leads to parsing bug Code: (1) signature Sig = sig structure a: sig structure b: sig end end structure a': sig end sharing a = a' structure b': sig end sharing b' = a.b sharing a' = b' end This example should be rejected because it would lead to a cycle in the signature for 'a' (the semantics Section 5.4). If one deletes the last sharing obtaining (2) signature Sig = sig structure a: sig structure b: sig end end structure a': sig end sharing a = a' structure b': sig end sharing b' = a.b end one get a legal program. However these examples do not survive parsing. (I get an "uncaught exception Notfound_Table"). Ignoring this, will your sharing algorithm cope with this subtlety? Messages: uncaught exception Notfound_Table (now fixed) Comments: We may not try to find cycles, since they would in any case prevent the signature from matching any structure. [dbm] Status: partially fixed in 0.20. cycle not detected, but exception is handled. -------------------------------------------------------------------------------- 34. uncaught Instantiate in type checking Submitter: Trevor Date: 4/14/88 Version: 0.18 Problem: uncaught Instantiate exception during type checking Code: structure foo = struct local exception Sort in fun sort (op > : ('x * 'x -> bool)) = let fun select(min, best, hd::tl) = select(min, if best > min then if best > hd andalso hd > min then hd else best else hd, tl) | select(min, best, nil) = best; fun lowest(best, hd::tl) = lowest( (if hd>best then best else hd), tl) | lowest(best, nil) = best; fun s (l as (hd::tl), min) = min | s _ = raise Sort in fn (l as (hd::tl)) => let val v = lowest(hd,tl) in v :: s(l, v) end | nil => nil end end (* local *) end Messages: uncaught exception Instantiate Comments: Status: fixed in 0.20. -------------------------------------------------------------------------------- 35. Compiler bug: abstractType Submitter: Andrew Date: 4/6/88 Version: 0.18 Problem: type error in functor definition causes Compiler bug error Code: signature FORMULA = sig type formula val NUM : formula end functor Parse(F : FORMULA) = struct fun parse() : F.formula = (0, F.NUM) (* val parse : unit -> F.formula = (fn () => (0, F.NUM)) -or- (* val parse : F.formula = (0, F.NUM) -- don't cause abstractType error *) end Messages: Error: expression and constraint don't agree (tycon mismatch) expression: int * ?.formula constraint: ?.formula in expression: (0,NUM) Error: Compiler bug: abstractType Status: fixed -------------------------------------------------------------------------------- 36. overloading resolution and order of recursive definitions Submitter: Dave Date: 5/2/88 Version: 0.18 Problem: overloading resolution can depend on the order in which mutually recursive definitions occur Code: fun f x = x + x and g() = f 1 (* + is not resolved *) fun g() = f 1 and f x = x + x (* + is resolved *) Status: fixed in 0.52, approximately. -------------------------------------------------------------------------------- 37. type printing Submitter: Nick Date: 5/3/88 Version: 0.18 Problem: valid path is not printed for a type Code: - signature SIG = sig type t val x: t end structure S: SIG = struct type t = int val x = 3 end; Messages: signature SIG structure S : <sig> - S.x; val it = 3 : ?.t ^ ??? Comments: Status: fixed in 0.20. (not sure how! as side-effect of another fix?) -------------------------------------------------------------------------------- 38. incompatible sharing raises Notfound_Table Submitter: Nick Date: 5/3/88 Version: 0.18 Problem: sharing specification between two incompatible structures causes an uncaught Notfound_Table exception. Code: - signature FOO1 = sig structure S: sig type S end structure T: sig type T end sharing S = T end; Messages: uncaught exception Notfound_Table Status: fixed in 0.20. Added handlers for Notfound_Table in function sMerge in typing/sharing.sml. -------------------------------------------------------------------------------- 39. type abbrev not recognized as function type Submitter: dbm Date: 5/12/88 Version: 0.19 Problem: type abbreviation expands to function type, but not recognized as a functional type by the type checker Code: type 'a church = ('a -> 'a) -> ('a -> 'a); val zero = fn f => fn x => x val succ = fn n => fn f => fn x => f (n f x) val pred = fn n : 'a church => ((fn (_,b)=>b) (n (fn (a,b) => (succ a, a)) (zero,zero))) Messages: Error: operator is not a function operator: 'a church in expression: n (fn (a,b) => (succ <exp>,a)) Comments: Status: fixed in 0.20. reduced the ratorTy in APPexp case of expType in typecheck.sml. -------------------------------------------------------------------------------- 40. Exception aliasing (match compiler) Submitter: Dave Date: 5/12/88 Version: 0.19 Problem: Match compiler doesn't cope with exception aliasing (through functor parameters, for instance). Status: fixed in 0.54 -------------------------------------------------------------------------------- 41. missing substructure Submitter: Dave Date: 5/18/88 Version: 0.19 Problem: substructure required by signature is not declared but appears anyway. Code: signature AS = sig val x: int end structure A : AS = struct val x = 3 end signature BS = sig structure A : AS end structure B : BS = struct open A end Messages: should complain, but doesn't Comments: Status: fixed in 0.20. -------------------------------------------------------------------------------- 42. Two signature matching problems. Submitter: Bob Harper Date: 5/20/88 Version: 0.18 Problem: (1) missing substructures found in environment, (2) bind exception processing sig specs after missing substructure Code: signature SIG = sig type t val x:t end; signature SIG' = sig structure S:SIG val y:S.t end; structure T : SIG = struct type t=int val x = 3 end; structure T' : SIG' = struct structure S=T val y=S.x end; (* This yields a sensible error message, then an uncaught exception Bind. *) structure T'' : SIG' = struct val y=T.x end; signature SIG'' = sig structure T:SIG val y:T.t end; (* This should not succeed, but it does! The unbound structure appears in the global environment, so it doesn't notice that the substructure T is missing. *) structure U : SIG'' = struct val y = T.x end; Messages: Comments: (1) missing substructure was found because lookSTR was being used to look for structure components in SigMatch.realize. Fixed by introducing lookSTRlocal that does not search through STRlayer. (2) TypesUtil.lookTycPath was causing bind exception because the missing substructure defaulted to the unexpected form INDstr(~1). Caused lookTycPath to raise an exception that was caught by typeInContext, which then returns ERRORty. SigMatch.compareTypes ignores the ERRORty. Status: fixed in 0.20 -------------------------------------------------------------------------------- 43. incorrect error message for sharing constraints Submitter: Bob Harper Date: 5/21/88 Version: 0.18 Problem: "unbound structure id in sharing spec" error message was reporting the wrong structure id. Code: signature SIG = sig end; signature SIG' = sig structure S:SIG end; (* Here it complains that S' is unbound in the sharing specification, but actually it's S'.T that is unbound! *) signature SIG'' = sig structure S':SIG' structure T:SIG sharing S'.T = T end; Messages: Error: unbound structure id in sharing specification: S' Comments: Moved one of the handlers for Notfound_Table from findStr to getStr in sharing.sml. 0.65 now gives output std_in:19.3-21.19 Error: unbound structure id in sharing specification: T it would be better to say that S'.T is unbound. Status: fixed in 0.20 -------------------------------------------------------------------------------- 44. subscript exception during parsing Submitter: Dave, Bob Harper Date: 3/20/88 Version: 0.18 Problem: Subscript exception raised during parsing Code: /usr/nml/bugs/bob.4, /usr/nml/examples/micro-ml/make Messages: uncaught exception Subscript Comments: path created by function search in EnvAccess.iterFct was in reversed order. added rev. Status: fixed in 0.20 -------------------------------------------------------------------------------- 45. equality on simple recursive datatype causes compiler to loop Submitter: Dave Date: 5/27/88 Version: 0.19 Problem: Compiling equality for a trivial recursive datatype causes the compiler to loop in Equal.equal.(test). Code: datatype t = A of t fun f(x:t) = (x=x) Comments: Of course this is a useless datatype, but someone could define it by mistake and cause the compiler to loop. The problem is the treatment of datatypes with a single transparent constructor in the function test in equal. It recursively calls test on the argument type of the constructor, which in this case is justs t again. A datatype like datatype t = A of t * int does not cause the loop. Status: fixed in 0.20 -------------------------------------------------------------------------------- 46. equality type checking and flexrecords Submitter: Dave Date: 6/3/88 Version: 0.20 Problem: when flexrecords are used a nonequality type may be accepted in a context where an equality record type is required Code: fun f(r as {a,...},true) = (r = r) (* checks only that a admits equality *) | f({b,...},false) = b 3 (* oops, the b field is a function! *) Messages: val f = fn : {a:''a,b:int -> bool} * bool -> bool (* argument type is not an equality type *) Comments: A fix probably requires a change in the way flexrecords are represented. Status: fixed in 0.54. [actually only correctly fixed in 0.85] -------------------------------------------------------------------------------- 47. scope of user bound type variable Submitter: Mads Tofte (Edinburgh) Date: 3/8/88 Version: 0.18 Problem: some uses of user-bound type variables have strange effects Code: fun f(x) = let val y : 'a = x in y y end; val f = fn : 'a -> 'a - f 3; Messages: Error: operator and operand don't agree (bound type var) operator domain: 'a operand: int in expression: f 3 Comments: y gets the type !'a.'a, which allows the expression "y y" to type check x gets the user bound type variable 'a as its type and it is not generalized either when y's type is generalized or when f's type is generalized the result type 'a refers to a generically bound type variable which coincidentally is printed as 'a Status: fixed in 0.20 generates an error message indicating that the user-bound type variable was propagated out of its scope. This is a rather obscure error message, but it is not easy to do better. This seems much better that allowing the propagation of the user bound type variable out of its natural syntactic scope, since it would be necessary to do arbitrary amounts of type checking to simply determine whether two explicit type variables are the same. -------------------------------------------------------------------------------- 48. printing of identity withtype declarations Submitter: Dave Date: 6/9/88 Version: 0.20 Problem: A simple identity declaration in the withtype clause of a datatype declaration will not be printed properly. Code: datatype foo = A withtype t = int; Messages: datatype foo con A : foo type t = t Comments: This happens because the backpatching of the type constructor puts the new name in the defining type as well as in the defined type binding. Status: fixed by 0.54 -------------------------------------------------------------------------------- 49. equality status of type constructors after functor application Submitter: Dave Date: 6/10/88 Version: 0.20 Problem: type constructors defined in a functor should sometimes become equality type constructors when the functor is applied, but they don't. Status: fixed in 0.20 (* unfixed in 0.56, refixed in 0.57? *) Given up on for the time being (since it's not required by the standard). (elg) -------------------------------------------------------------------------------- 50. free refs to sibling structures within a signature Submitter: Dave Date: 6/13/88 Version: 0.20 Problem: Free references to a sibling structure in a signature are not allowed Code: signature SS = sig structure A : sig type t end structure B : sig val x : A.t end end Messages: Error: free ref to sibling struct in sig not implemented Comments: Outer signature env has default info, giving rise to Subscript exception when attempting to interpret A. Status: fixed in 0.31 -------------------------------------------------------------------------------- 51. free refs to param struct in functor result signature Submitter: Dave Date: 6/13/88 Version: 0.20 Problem: Free references to the functor parameter are not allowed in the result signature. Code: functor F(S: sig type t val x: t end) : sig val y : S.t end = struct val y = S.x end Messages: Error: unbound head structure: S in path: S.t Comments: Status: fixed in 0.39 ------------------------------------------- 52. input of large strings Submitter: Appel&Duba Date: 9/9/88 Version: 0.20 System: any Problem: (input f k) was unreliable for k>1024 Status: fixed in 0.22 ------------------------------------------- 53. exportFn broken Submitter: Appel&Duba Date: 9/9/88 Version: 0.20 System: any Problem: exportFn produced an executable that dumped core Status: fixed in 0.22 ------------------------------------------- 54. problems in Sun Unix version 4.0 Submitter: Appel&Duba Date: 9/9/88 Version: 0.20 System: Sun 3/SunOS 4.0 Problem: doesn't work; can't boot sml Status: fixed in 0.22 ------------------------------------------ 55. type constraint on field abbreviation Submitter: Duba Date: 11/2/88 Version: 0.22 System: any Problem: won't except type constraint in abbreviated records Code: fun f{x : int} = 1; Message: Error: expected EQUAL after label, found COLON Status: fixed ------------------------------------------ 56. big integer constants Submitter: Duba Date: 11/8/88 Version: 0.22 System: cps Problem: interger constants must be less than 31 bits Code: 1000000000 Message: Error: Compiler bug: Overflow in cps/generic.sml Status: fixed in 0.24 --------------------------------------------------------------------------- 57. open_out causes SystemCall exception Submitter: dbm Date: 11/10/88 Version: 0.23 System: -- Problem: opening nonwriteable file causes uncaught exception SystemCall Code: LexGen.lexGen "ml.lex"; uncaught exception SystemCall - system "ls -l"; total 38 -r--r--r-- 2 dbm 993 Nov 9 12:03 ascii.sml -r--r--r-- 2 dbm 3207 Nov 9 12:03 hookup.sml -r--r--r-- 2 dbm 2813 Nov 9 12:03 ml.lex -r--r--r-- 2 dbm 23900 Nov 9 12:03 ml.lex.sml -r--r--r-- 2 dbm 2698 Nov 9 12:03 symbols.sml -r--r--r-- 2 dbm 2599 Nov 9 12:03 timelex.sml val it = () : unit Messages: Comments: Attempting to open an unreadable file for input raises Io_failure, but attempting to open an unwriteable file for output raises SystemCall. Status: fixed. --------------------------------------------------------------------------- 58. incorrect string value in Io_failure exception Submitter: dbm Date: 11/10/88 Version: 0.23 System: vax/v9 Problem: string returned by Io_failure invoked by open_in is bogus Code: [assume "all" is the name of an unreadable file] (open_in "all"; "abc") handle Io_failure s => s; Messages: val it = "open_in: open" : string Comments: should be "open_in: all" Status: fixed in 0.49. --------------------------------------------------------------------------- 59. memory fault on sun Submitter: Benjamin Pierce, CMU (Benjamin.Pierce@prood.ergo.cs.cmu.edu) Date: 10/18/88 Version: 0.22 System: Sun 3 / SunOS 4.0 (3.x?) Problem: memory fault Code: see shamash:/usr/sml/bugs/benli/test1.sml Messages: see shamash:/usr/sml/bugs/benli/log1 Comments: Test program works on Vax Status: fixed in 0.24 [bug in polymorphic equality for constructions] --------------------------------------------------------------------------- 60. floating point coprocessor problem on Sun 3 Submitter: M. C. Atkins, University of York, UK., ...!ukc!minster!martin Date: 10th Nov 1988 Version: 0.22, 10 October 1988 System: Sun3/SunOS 3.5 Problem: sml core dumps with illegal instruction (COPROCESSOR PROTOCOL ERROR) Code: (This is what I was given!) val start_seed1 = 0.71573298; val start_seed2 = 0.31872973; val start_seed3 = 0.45832123; val mul1 = 147.0; val mul2 = 375.0; val mul3 = 13.0; fun random seed mul = let val x = seed*mul*3.0 in x - real(floor x) end; fun randlist seed1 seed2 seed3 0 = [] | randlist seed1 seed2 seed3 n = let val s1 = random seed1 mul1 val s2 = random seed2 mul2 val s3 = random seed3 mul3 val rn = (floor ((random (s1*s2*s3) 743.0)*37.0) ) in rn::(randlist s1 s2 s3 (n-1)) end; fun rlist n = randlist start_seed1 start_seed2 start_seed3 n; Messages: No compiler messages. At runtime the following is written to the console: sml: USER COPROCESSOR PROTOCOL ERROR trap address 0x34, pid 147, pc = ea92a, sr = 4, stkfmt 9, context 3 D0-D7 3 3 196838 f 0 0 1966b0 efffc50 A0-A7 efff274 1affec 0 efffd98 efffda4 0 1b0004 efff264 Comments: To duplicate `use' the given code, and then evaluate `rlist 300' two or three times. Typically the first evaluation succeeds, but subsequent evaluations fail, giving a core dump (Illegal Instruction) and the above error on the console. I have duplicated the behaviour on both a Sun 3/50, and a Sun 3/280 - both equipped with MC68881 floating point coprocessors. /usr/etc/mc68881version gives the following output: on 3/50: MC68881 available; mask set appears to be A93N. Approximate MC68881 frequency 16.5 MHz. on 3/280: MC68881 available; mask set appears to be A93N. Approximate MC68881 frequency 20.3 MHz. Status: fixed in 0.31 --------------------------------------------------------------------------- 61. lexer bug Submitter: Trevor Date: 11/6/88 Version: 0.22 System: any? Problem: illegal character causes loss of next line of input Code: - 234;^? (* That's a true delete (or ^A or whatever) that accidentally *) val it = 234 : int (* got stuck in there. *) Error: illegal character - "hello"; (* This line gets discarded *) - 3; val it = 3 : int - Comments: Status: fixed in 0.24 --------------------------------------------------------------------------- 62. share runtime on SunOS 3.n Submitter: Nick Date: 10/28/88 Version: 0.22 System: Sun 3, SunOS 3.n Problem: runtime built with share parameter doesn't work on SunOS 3.n Comment: SunOS 3.n object format is not supported Status: no action --------------------------------------------------------------------------- 63. curried, clausal def of infix function Submitter: Paulson Version: Version 0.20, 13 June 1988 System: Sun3/SunOS Problem: parsing of infixes Code: (minimal code fragment that causes bug) - infix orelf; - fun (f orelf g) x = 0; Error: expected EQUAL, found RPAREN Error: atomic expression expected Error: declaration or expression expected, found RPAREN - fun f orelf g = fn x => 0; val orelf = fn : 'a * 'b -> 'c -> int Comments: This use of an infix in a pattern seems legal and is accepted by Poly/ML. Status: fixed in 0.54 --------------------------------------------------------------------------- 64. unclosed comment is not reported Submitter: Duba Date: 12/2/88 Version: 0.22 and later System: Any Problem: unclosed comment is not reported Code: (* ... Status: fixed in 0.54. --------------------------------------------------------------------------- 65. arrayoflist should have weak type. Submitter: Nick Date: 11/24/88 Version: 0.24 Status: fixed in 0.33 --------------------------------------------------------------------------- 66. floor(~3.9) gives ~5. Submitter: Nick Date: 11/24/88 Version: 0.24 System: Sun 3 Status: fixed in 0.33 --------------------------------------------------------------------------- 67. won't parse "fn {x: ty} => x". Submitter: Nick Date: 11/24/88 Version: 0.24 System: Sun 3 Status: fixed in 0.33 --------------------------------------------------------------------------- 68. spurious error message -- doesn't match sig spec Submitter: Nick Date: 11/24/88 Version: 0.24 System: Sun 3 Code: - structure S: sig val x: int end = struct val x = hd "s" end; Error: operator and operand don't agree (tycon mismatch) operator domain: 'S list operand: string in expression: hd "s" Error: value type in structure doesn't match signature spec name: x spec: int actual: error Status: fixed in 0.54 --------------------------------------------------------------------------- 69. printing of exn spec in inferred signature Submitter: Nick Date: 11/24/88 Version: 0.24 System: Sun 3 Code: - structure Blah = struct exception BLAH end; structure Blah : sig exception BLAH of exn (* "of exn" should not appear *) end Status: fixed in 0.54 --------------------------------------------------------------------------- 70. constructor shouldn't appear in printed structure signature Submitter: Nick Date: 11/24/88 Version: 0.24 System: Sun 3 Code: signature SIG = sig type t end structure S:SIG = struct datatype t = foo of int val x = 3 end Messages: structure S : sig datatype t con foo : int -> t (* shouldn't be printed *) end Comment: constructor foo is not accessible as component of S Also, from Dave Berry (2/2/89): NJ ML prints the constructors of a datatype when that datatype is matched against a "type" in a signature, even if the signature doesn't include the constructors. This seems a trivial point (except that it's confusing for the novices on the course we teach). However, with some complicated programs the compiler bombs out, raising the subscript exception. You are left in the ML system, but it won't compile your code. I don't have a small example of this. It first hit me preparing examples for the aforementioned course, and it's just hit me again. Status: fixed in 0.56 --------------------------------------------------------------------------- 71. Failure to restore enviroment after exception in "use" Submitter: Nick Date: 11/24/88 Version: 0.24 System: Sun 3 Code: For a file "y.sml" containing "val y = 4"; - val x = (use "y.sml"; let exception X in raise X end ); [opening y.sml] val y = 4 : int [closing y.sml] uncaught exception X - (* so far so good... *) - x; uncaught exception Runbind Comment: needs to be a protect around use to trap exceptions and restore env Status: fixed in 0.54 --------------------------------------------------------------------------- 72. equality types with abstype declarations Submitter: kevin Date: 11/30/88 Version: 0.24? System: Sun 3 Code: (* The following definition is accepted by the compiler, resulting in the declaration test: ''a foo -> bool *) abstype 'a foo = Foo of 'a list with fun test(Foo x) = (x = []) end; (* The next declaration fails with the error Error: operator and operand don't agree (equality type required) operator domain: ''S * ''S operand: 'T foo * 'U foo in expression: x = Foo nil *) abstype 'a foo = Foo of 'a list with fun test(x as Foo _) = (x = Foo []) end; (* I'm not sure why one should be allowed and not the other - the old Edinburgh compiler accepted both. *) Status: fixed in 0.54 --------------------------------------------------------------------------- 73. strange function definition Submitter: Trevor Date: 12/10/88 Version: 0.24? System: vax Problem: Code: - fun add-a x = x+1; val a = fn : int -> int - a 3; val it = 4 : int Comments: The intent was to have a hyphen in a function name (something like "fun add_a ...". Status: fixed in 0.54 --------------------------------------------------------------------------- 74. withtype with identity type definition (printing only?) Submitter: Nick Date: 12/15/88 Version: 0.22 Code: - datatype Foo = FOO of Forest = withtype Forest = Tree list = and Tree = Foo; datatype Foo con FOO : Forest -> Foo type Forest = Tree list type Tree = Tree <-= Huh? Comments: probably an artifact of printing from symbol table, not abstract syntax Status: fixed in 0.54 --------------------------------------------------------------------------- 75. improper type variable causes Substring exception Submitter: John Reppy Date: 12/17/89 Version: 0.24 System: Sun 3 Code: - (nil : ' list); uncaught exception Substring Status: fixed in 0.56 --------------------------------------------------------------------------- 76. parenthesized infix expression in fun lhs Submitter: Dave Berry Date: 12/22/88 Version: 0.24? Code: infix o; fun (f o g) x = f (g x); Comments: This is correct according to the Definition (according to Berry) Status: fixed in 0.54 --------------------------------------------------------------------------- 77. unparenthesized infix expressions in fun lhs Submitter: Dave Berry Date: 12/22/88 Version: 0.24? Code: infix 4 %; infix 3 %%; datatype foo = op % of int * int; fun a % b %% c % d = 0; NJ ML accepts this, as does Edinburgh ML. It is incorrect; brackets are required as follows: fun (a % b) %% (c % d) = 0; This is defined on page 68 of the definition. The lhs and rhs of the infixed operator being defined are required to be atomic patterns. Status: fixed in 0.54 --------------------------------------------------------------------------- 78. bad signature allowed Submitter: Nick Date: 1/20/89 Version: 0.24 Code: signature FRED = sig type Fred val x: 'a Fred end Comments: This should be caught as an ill-formed signature Status: fixed in 0.39 --------------------------------------------------------------------------- 79. withtype Submitter: Simon (from abstract hardware) via Mike Fourman Date: 1/31/88 Version: 0.24 Problem: "Did you know that the following is not valid ML? datatype type1 = T of type2 * type3 withtype type2 = int (* this could be a large expression *) and type3 = type2 * string; The reason is that the "datatype datbind withtype typbind" construct is expanded out into "datatype datbind'; type typbind" where "datbind'" is the the result of using "typbind" to expand "datbind". Note that this construct does *not* expand "typbind" itself, so "type2" is out of scope in its occurrence in "type3". This simultaneous definition property of "withtype" is quite annoying, especially as there is no way to get the effect of sequential definition (other than manually expanding out the body of "type3" - but that is precisely the problem that "withtype" is supposed to solve)." Code: - datatype type1 = T of type2 * type3 withtype type2 = int (* this could be a large expression *) and type3 = type2 * string; - = = Error: Compiler bug: defineEqTycon/eqtyc 1 - datatype type1 = T of type2 * type3 withtype type3 = type2 * string withtype type2 = int (* this could be a large expression *); - = = Error: unbound type constructor (in datatype): type2 Error: unbound type constructor (in datatype): type2 Error: Compiler bug: defineEqTycon/eqtyc 1 - Comment: withtype should have sequential bindings, not simultaneous Status: fixed in 0.54 --------------------------------------------------------------------------- 80. simultaneous type declarations Submitter: Dave Berry Date: 2/1/89 Version: 0.24 Code: - type type2 = int = and type3 = type2 * string; type type2 = int type type3 = type2 * string Comments: This is wrong: type2 shouldn't be bound before the declaration of type3. Status: fixed in 0.54 --------------------------------------------------------------------------- 81. repeated specs in signatures Submitter: John Reppy Date: 2/12/89 Version: 0.24 Problem: I noticed that a signature of the form sig val x : int val x : string end is acceptable. Although this is in keeping with redeclaration in other scopes, it isn't very useful, and lets detectable errors get by. I would suggest that redeclaration of identifiers in signatures ought to at least generate a warning message (if not an error). Status: same as #4 --------------------------------------------------------------------------- 82. compiler bug caused by type in datatype declaration Submitter: Andrew Date: 2/20/89 Version: 0.28? Code: datatype a = A of int; datatype b = B of A; (* typo for B of a *) Messages: Error: unbound type constructor (in datatype): A Error: Compiler bug: defineEqTycon/eqtyc 1. Status: fixed in 0.39 --------------------------------------------------------------------------- 83. unexpected parsing of erroneous datatype declaration Submitter: Carl Gunter Date: 2/24/88 Version: 0.20 Code: - datatype complex = Complex (real,real); datatype complex con Complex : complex val it = (fn,fn) : (int -> real) * (int -> real) Comments: implicit "val it = " inserted after constructor Complex breaks the declaration into a valid datatype declaration and a top-level value expression (implicit value declaration). This could probably be detected and suppressed. Status: fixed in 0.54 --------------------------------------------------------------------------- 84. definition of open_out and open_append Submitter: Nick Date: 2/28/89 Version: 0.29 Problem: the following code from perv.sml is faulty: val open_out = open_o WRITE handle Assembly.SystemCall s => raise Io("open_out: " ^ s) val open_append = open_o APPEND handle Assembly.SystemCall s => raise Io("open_append: " ^ s) Another lambda-abstraction is needed to catch errors on the application of open_o, rather than these bindings. Status: fixed in 0.33 --------------------------------------------------------------------------- 85. bad error message for failed signature match Submitter: John Reppy Date: 3/6/89 Version: 0.28 Code: structure Foo : sig type foo val f : foo -> int end = struct type Foo = int fun f x = x end; Messages: Error: unmatched type spec: foo tycStamp: INDtyc [] Error: Compiler bug: tycStamp Status: fixed in 0.54 --------------------------------------------------------------------------- 86. incorrectly allows redefining of "=" Submitter: Dave Berry Date: 3/15/89 Version: 0.29 Problem: NJML handles the = symbol incorrectly in some cases. - val op = = op = ; - nonfix =; - = (true, true); Error: declaration or expression expected, found EQUAL Comment: The = symbol may not be redefined (Definition, page 4). The top definition does seem to redefine =, despite the lack of response from the system. I can't see anything in the Definition that forbids making = nonfix, so I suppose it should be possible to use it in a nonfix way. Status: fixed by 0.69 (rebinding = gives a warning message; parses better) --------------------------------------------------------------------------- 87. execute subprocess dies on interrupt on blocked input Submitter: dbm Date: 3/19/89 Version: 0.31 System: Sun3/100, SunOS 4.0.1; VAX8550, V9 Problem: interrupting blocked call of input from execute subprocess kills subprocesss Code: val (ins,outs) = execute "cat" input ins 5; ^Cuncaught exception Interrupt Messages: After interrupt, System.system("ps x"), indicates that "cat" subprocess has disappeared, and subsequent attempt to flush output to outs raises exeption Io("output: write failed"). Comments: end_of_stream also blocks, and interrupting a call of end_of_stream seems to have the same effect. jhr: This isn't a bug, but rather a "feature." The sub-process inherits the control terminal (/dev/tty) from its parent. This means that the SIGINT generated by ^C is passed to both processes. I assume that there is a work-around, but the semantics are correct for Unix. Status: not a bug --------------------------------------------------------------------------- 88. subscript exception while printing type Submitter: Thorsten Altenkirch Technische Universitaet Berlin alti%theo@tub.BITNET Date: Fri Mar 31 18:42:20 MET DST 1989 Version: 0.24 System: SunOS Release 4.0_Export Problem: "uncaught exception Subscript" while printing type. Code: signature A = sig type t end; functor F1(a:A) = struct datatype t2 = f of a.t end; functor F2(a:A) = struct structure S = F1(a); open S end; structure SA = struct type t = int end; structure F2SA = F2(SA); Messages: .. structure F2SA : sig structure S : sig...end datatype t2 con f : [closing /tmp/sml.tmp.l10641] uncaught exception Subscript Comments: The error may be caused by the handling of indirect types in src/basics/printtype.sml (printPath). Status: fixed in 0.39 --------------------------------------------------------------------------- 89. continuation line string escape at beginning of string Submitter: dbm Date: 4/3/89 Version: 0.33 System: Sun 3, SunOS 4.0.1 Code: - "\ (* CR after \ at beginning of string *) - akdk"; Error: unclosed string = (* second CR typed *) Error: unclosed string Error: unbound variable kdk = ; Error: operator is not a function operator: string in expression: "" kdk Status: fixed in 0.49. --------------------------------------------------------------------------- 90. secondary prompt is not set in multi-line strings and comments. Submitter: dbm and duba Date: 4/3/89 Version: 0.33 System: All Status: fixed in 0.49 --------------------------------------------------------------------------- 91. misparsing of fun lhs Submitter: dbm and duba Date: 4/3/89 Version: 0.33 System: All Code: - fun a+b (x) = a; Error: Compiler bug: generalizeTy -- bad arg b : 'S -> undef Status: fixed in 0.54 --------------------------------------------------------------------------- 92. uncaught Nth exception after type constructor arity mismatch in sigmatch Submitter: David Tarditi, Princeton University, drt@notecnirp.princeton.edu Date: 6/23/89 Version: 0.33 System: Vax/4.3 BSD Problem: Mismatching arities on types causes uncaught exception Nth later in signature checking. Example: functor OrdSet(B : sig type elem val gt : elem * elem -> bool val eq : elem * elem -> bool end) = struct end structure Bad = struct type 'a elem = int * 'a val gt = fn ((a:int,_),(b,_)) => a > b val eq = fn ((a:int,_),(b,_)) => a = b end structure X = OrdSet(Bad) Result: Standard ML of New Jersey, Version 0.33, 1 April 1989 val it = () : unit std_in, line 18: Error: mismatching tycon arities: elem uncaught exception Nth Comments: The uncaught exception Nth appears to occur while matching the actual types of eq and gt against the types in the signature of the formal structure parameter. Status: fixed in 0.56 --------------------------------------------------------------------------- 93. type propagation failure with functor application Submitter: David Tarditi, Princeton University, drt@notecnirp Date: 7/25/89 Version: 0.33 System: Vax/4.3 BSD Problem: Type in a structure passed to a functor remains an opaque type outside the functor. Example code: signature T = sig type 'pos token end signature L = sig structure T : T end functor P(structure L : L) = struct open L end structure L = struct structure T = struct type 'a token = int * 'a * 'a end end structure B = P(structure L = L) val x = (5,"","") val _ = x : string L.T.token (* this works *) val _ = x : string B.T.token (* this causes a type error - why ? *) Comments: I thought that the type token should be an abstract (opaque) type only inside the functor P. It should be non-opaque in the structure created by applying the functor P. Status: fixed in 0.37 --------------------------------------------------------------------------- 94. uncaught Bind exception parsing functor body Submitter: David Tarditi, Princeton University, drt@notecnirp Date: 7/25/89 Version: 0.33 System: Vax/4.3 BSD Problem: The compiler failed by raising a Bind exception which was not caught. Example code: functor mkDummy () : sig end = struct end functor mkLalr () = struct datatype lcore = LCORE of int end functor mkTable () = struct structure Dummy = mkDummy() structure Lalr = mkLalr() val x = fn (Lalr.LCORE l) => l end Comment: It seems that the compiler fails while compiling an access to a data constructor inside a functor. The data constructor must have the special characteristic that it is created by applying another functor inside the functor being compiled: Status: fixed in 0.37 (0 should have been 1 in envaccess.sml *) --------------------------------------------------------------------------- 95. infix declaration interferes with type parsing Submitter: David Tarditi, Princeton University, drt@notecnirp Date: 4/30/89 Version: 0.33 System: Vax/4.3 BSD Problem: Spurious declaration of infix for an identifier causes problems when it is used as a type constructor later. Sample Run: Standard ML of New Jersey, Version 0.33, 1 April 1989 val it = () : unit - type ('a,'b) --> = 'a -> 'b; type ('a,'b) --> = 'a -> 'b - val a = fn _ => 5; val a = fn : 'a -> int - a : ('a,int) -->; val it = fn : 'a -> int - infix -->; - a : ('a,int) -->; Error: (user) bound type variable propagated out of scope it : 'aU -> int Comments: The declaration of an identifier to be infix should not affect type constructors. Infix declarations apply only to data constructors and value identifiers. The declaration of '-->' to be infix should not affect the use of '-->' as a type constructor, even though the declaration is spurious. P.S. Maybe there should be a way to declare type identifiers to be infix. I was trying to declare '-->' to be infix because I was creating different kinds of arrows for my effects inference. --> could denote a function that is pure, while -*-> could denote a function with an effect. I need to do this to bootstrap the pervasive environment without assuming that all built-in functions have side-effects. Status: fixed in 0.54 --------------------------------------------------------------------------- 96. uncaught exception Unbound parsing signature Submitter: Martin Wirsing Date: 7/18/89 Version: 0.33 System: VAX/V9 Description: uncaught exception Unbound while parsing a signature Code signature Sigtest = sig structure S: sig type t1 val x:t1->t1 end structure R: sig type t2 val x:t2->t2 end type t val f:t1->R.t2 end = = = = = = = = = = = = = uncaught exception Unbound - Error: declaration or expression expected, found END Status: fixed in 0.39 --------------------------------------------------------------------------- 97. Type checking Submitter: Mads Tofte Date: 6/30/89 Version: 0.33 Description: Here is a program which, although type correct, does not type check on the NJ compiler --- one gets a type error in the last line. It does type check on Poly ML. The problem disappears is one erases the explicit result signature on SymTblFct and it seems that the problem is that sharing is not propagated correctly in functor application when the signature has an explicit result signature. When the internal type stamps are printed, one sees that the types of the second and the third arguments are ``abstract'' and not instantiated to the stamps for string and real, respectively. Code: signature IntMapSig= sig type 'a map exception NotFound val apply: 'a map * int -> 'a val update: 'a map * int * 'a -> 'a map val emptyMap: 'a map end; signature ValSig = sig type value end; signature SymSig= sig eqtype sym val hash: sym -> int end; functor SymTblFct( structure IntMap: IntMapSig structure Val: ValSig structure Sym: SymSig): sig type table exception Lookup val emptyTable: table val update: table * Sym.sym * Val.value -> table end= struct datatype table = TBL of (Sym.sym * Val.value)list IntMap.map val emptyTable = TBL IntMap.emptyMap; exception Lookup fun update(TBL map,s,v)= let val n = Sym.hash(s) val l = IntMap.apply(map,n) handle IntMap.NotFound => [] val newmap= IntMap.update(map,n,(s,v)::l) in TBL newmap end end; functor FastIntMap(): IntMapSig= struct (* dummy implementation of int maps *) datatype 'a map = N of int * 'a * 'a map * 'a map | EMPTY val emptyMap = EMPTY exception NotFound fun apply _ = raise NotFound; fun update _ = raise NotFound; end; functor ValFct(): ValSig= struct type value = real end; functor SymFct(): SymSig= struct type sym = string fun hash(s:sym)= ord s end; structure MyTbl= SymTblFct(structure IntMap = FastIntMap() structure Val = ValFct() structure Sym = SymFct() ); open MyTbl; update(emptyTable,"ape",10.0); Comment: parameters Val and Sym appear in result signature of SymTblFct. This has not been supported previously. Status: fixed in 0.37 --------------------------------------------------------------------------- 98. eqtype determination Submitter: Carl Gunter (gunter@linc.cis.upenn.edu) [Jakov Kucan] Date: 7/18/89 Version: 0.33 Problem: compiler bug: defineEqTycon/eqtyc 1 Code: datatype constant_type = CONSTANT; datatype composed_type = Constructor of int * CONSTANT; Messages: Standard ML of New Jersey, Version 0.20, 13 June 1988 val it = () : unit - use "bug.ml"; [opening bug.ml] datatype constant_type con CONSTANT : constant_type bug.ml, line 7: Error: unbound type constructor (in datatype): CONSTANT bug.ml, line 7: Error: Compiler bug: defineEqTycon/eqtyc 1 Status: fixed in 0.37 --------------------------------------------------------------------------- 99. include bug Submitter: Nick Rothwell Date: 7/19/89 Version: 0.33 Problem: include doesn't work Code: signature A = sig end signature B = sig include A end; Messages: Error: Compiler bug: SigMatch.setParent Status: fixed in 0.39 --------------------------------------------------------------------------- 100. constructor not printed after open declaration Submitter: Nick Rothwell Date: 7/18/89 Version: 0.33 Problem: In this case, a datatype is being printed as a type: the constructor isn't shown (although it's still bound): Code: - signature X = sig datatype T = T end; signature X = sig datatype T con T : T end - structure X: X = struct datatype T = T end; structure X : sig datatype T con T : T end - open X; type T = T Status: fixed in 0.49 --------------------------------------------------------------------------- 101. Duplicate labels (in either types or values) are not detected Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: - {x=1,x=true} : {x:int,x:bool}; val it = {x=1,x=true} : {x:int,x:bool} Status: fixed in 0.54 --------------------------------------------------------------------------- 102. One-tuples are not printed sensibly. Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: - (* a one-tuple *) {1 = 999}; val it = (999) : int - it = 999; Messages: Error: operator and operand don't agree (tycon mismatch) operator domain: (int) * (int) operand: (int) * int in expression: it = 999 Status: fixed in 0.54 --------------------------------------------------------------------------- 103. Space missing in an error message (which might be more informative). Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: - {999}; Messages: Error: numeric label abbreviation999 Status: fixed in 0.54 --------------------------------------------------------------------------- 104. Labels with leading zeroes should not be accepted (this is made explicit on page 5 of version 3 of the Standard). Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: - {0000002 = 999}; val it = {2=999} : {2:int} Status: fixed in 0.54 --------------------------------------------------------------------------- 105. Large numeric labels are disallowed. Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: - {9999999999999999999999 = 999}; Messages: Error: integer too large Error: nonpositive integer label, found 0 Status: not important --------------------------------------------------------------------------- 106. Something strange is happening with "it". Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: Standard ML of New Jersey, Version 0.33, 1 April 1989 val it = () : unit - raise it; Error: argument of raise is not an exception raised: unit in expression: raise it - raise it; Error: argument of raise is not an exception raised: unit in expression: raise it - raise it; uncaught exception Runbind - raise it; uncaught exception Runbind - Comment: The problem of an exception leaving the system in an uncertain state seems to occur in other contexts too. Status: fixed in 0.54 --------------------------------------------------------------------------- 107. NJML disappears into an infinite loop when trying to parse large real numbers; presumably some error recovery code is flakey. Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: - 1.0E308; val it = 1.0E308 : real - 1.0E309; Error: Real constant out of range - 2.0E308; (* wait a long time ... *) val it = uncaught exception Interrupt - Comment: Furthermore, a failing program elaboration or evaluation (such as the above) should not rebind the variable "it" (ML Standard v3, rules 194 and 195). NJML sometimes does (as above). Furthermore, trying to print "it" when it has been bound to such an exception sometimes seems to crash the system (it refuses to respond to further input); at other times the exception Runbind is raised. Does anyone know why the largest integer NJML will parse is 1073741775 ? This is 2^30 - 49, which seems a funny number to choose. (Mike Crawley suggests the fact that 49 is the ASCII code for "1" may be significant.) Status: fixed in 0.56 --------------------------------------------------------------------------- 108. More faulty error recovery? Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: - (* calculates ~ 2^30 *) ~1073741775 - 49; [Increasing heap to 4096k] [Major collection... 99% used (973164/976372), 8020 msec] [Increasing heap to 7568k] val it = uncaught exception Interrupt - Status: fixed in 0.56 --------------------------------------------------------------------------- 109. sharing of datatypes not handled properly Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk) Date: 7/28 Version: 0.33 Code: signature EQSIG = sig type r datatype s = S of r and t = T of s sharing type r = t end; functor F(X : EQSIG) = struct fun test(x : X.t) = (x = x); end; Messages: signature EQSIG = sig type r datatype s con S : r -> s datatype t con T : s -> t end Error: operator and operand don't agree (equality type required) operator domain: ''S * ''S operand: ?.t * ?.t in expression: x = x Error: Compiler bug: abstractType Comment: Both are wrong, as the signature EQSIG elaborates to the same semantic object as the following (which both treat correctly): signature EQSIG = sig type r datatype s = S of t and t = T of s sharing type r = t end; Status: fixed in 0.54 --------------------------------------------------------------------------- 110. val rec Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: val rec form of definition rejected Code: - val x = 1 and rec y = fn z => z; (* should compile *) Error: expected an atomic pattern, found REC Error: expected EQUAL, found REC Error: atomic expression expected, found REC Error: declaration or expression expected, found REC Comment: the compiler should accept the above declaration. Status: not a bug; the Definition is silly --------------------------------------------------------------------------- 111. local polymorphic definitions Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: local polymorphic definitions rejected Code: - val q = let exception x of '_a in 1 handle x _ => 2 end; Error: type variable in exception type not weak enough - local exception x of '_a in val q = 1 handle x _ => 2 end; Error: type variable in exception type not weak enough Comment: the compiler should accept both the above definitions, which are valid, since the imperative type variable '_a is *not* free in the top level declaration. Comment: (dbm) Consider the following, which leads to insecurity: local exception X of '_a in val exn0 = X(3) fun h(X(b:bool)) = b end; raise exn0 handle e => h(e); Status: not a bug --------------------------------------------------------------------------- 112. equality Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: equality misbehaving Code: (0.0 = ~0.0, 0.0 = ~ 0.0, ~0.0 = ~ 0.0); (* (true,true,true) *) infix eq; fun x eq y = x = y; (0.0 eq ~0.0, 0.0 eq ~ 0.0, ~0.0 eq ~ 0.0); (* (true,false,false) *) infix eq; fun (x:real) eq y = x = y; (0.0 eq ~0.0, 0.0 eq ~ 0.0, ~0.0 eq ~ 0.0); (* (true,true,true) *) Comment: the polymorphic equality function should give consistent results, even when the type of its argument is known to be real. Status: fixed in 0.49 --------------------------------------------------------------------------- 113. empty declarations Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: Parsing empty declarations Code: let val x = 1; (* empty declaration *) ; val y = 2 in x + y end; Error: expected IN, found SEMICOLON Error: atomic expression expected, found SEMICOLON Error: atomic expression expected, found VAL Error: expected END, found VAL Error: declaration or expression expected, found IN Comment: the above program is syntactically correct. Status: fixed in 0.49 --------------------------------------------------------------------------- 114. include broken (same as bug 99) Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: include in signatures Code: - signature old = sig type t end; signature old = sig type t end - signature new = sig include old end; Error: Compiler bug: SigMatch.setParent Status: fixed in 0.39 --------------------------------------------------------------------------- 115. cyclic signatures Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: cyclic signatures Code: (* shouldn't be allowed, since object (signature) is not cycle-free *) signature bad = sig structure A : sig structure B : sig end; end; sharing A = A.B; end; Comment: NJML accepts the above signature declaration, which should be rejected because it elaborates to a cyclic semantic object; cyclic objects are not semantically admissible. Status: not a bug? (signature will never match a structure) --------------------------------------------------------------------------- 116. pattern declares no variables warning (?) Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: Missing warning message Code: let val _ = 1 in 2 end; local val _ = 1 in val it = 2 end; Comment: Each of the above should produce a "Pattern declares no variables" warning message, but neither does. Status: not a bug --------------------------------------------------------------------------- 117. sharing and equality attributes Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: problems with equality attribute Code: (***************************************************************************) (* This is illegal in version 3 of the ML standard *) (* s may only be elaborated to a non-equality type (+ extra bits) *) (* t may only be elaborated to an equality type (for consistency with its *) (* constructor environment) *) (* Hence s and t can't share *) (***************************************************************************) signature BADSIG = sig datatype s = Dummy of bool -> bool datatype t = Dummy of int sharing type s = t; end; Comment: NJML accepts this signature but shouldn't. Getting the equality attribute right in the presence of sharing constraints seems to be quite a tricky problem. Status: fixed in 0.56 --------------------------------------------------------------------------- 118. deviation from Definition, div and mod Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: div / mod give non-standard results Code: fun divmod (m,n) = (m div n,m mod n); (* should give (1,2) *) divmod(5,3); (* gives (1,2) *) (* should give (~2,1) *) divmod(~5,3); (* gives (~1,~2) *) (* should give (~2,~1) *) divmod(5,~3); (* gives (~1,2) *) (* should give (1,~2) *) divmod(~5,~3); (* gives (1,~2) *) Comments: I'd like the initial dynamic basis to conform to the Standard. (More efficient, non-standard versions should be hidden away.) Status: fixed in 0.56 --------------------------------------------------------------------------- 119. deviation from Definition Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: I/O functions are curried, Standard has them uncurried Code: - input; val it = fn : instream -> int -> string Comments: I'd like the initial dynamic basis to conform to the Standard. (More efficient, non-standard versions should be hidden away.) Status: fixed in 0.56 --------------------------------------------------------------------------- 120. deviation from Definition Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: Prelude functions raise the wrong exceptions Code: 0.0 / 0.0; (* raises Overflow *) 1.0 / 0.0; (* raises Real *) Comments: I'd like the initial dynamic basis to conform to the Standard. (More efficient, non-standard versions should be hidden away.) This one is even trickier; Poly/ML doesn't raise any exception at all for these (it prints NaN.0 and Infinity.0 respectively). Status: fixed in 0.56, mostly --------------------------------------------------------------------------- 121. Unimplemented parts of Standard Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: open in signatures apparently unsupported Code: - structure old = struct type t = int end; structure old : sig eqtype t end - signature new = sig open old end; Error: expected END, found OPEN Error: declaration or expression expected, found END - Status: This is a language design problem; see doc/localspec --------------------------------------------------------------------------- 122. Unimplemented parts of Standard Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: let and local for structures apparently unsupported Code: - structure Y = struct local val x=1 in structure X = struct val y = 1 end end end; Error: expected END, found STRUCTURE Error: declaration or expression expected, found END - structure Y = let val x=1 in struct structure X = struct val y = 1 end end end; Error: expected a structure-expression, found LET - Status: fixed in 0.54 --------------------------------------------------------------------------- 122. Unimplemented parts of Standard Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 7/18/89 Version: 0.33 System: Sun3/SunOS 4.0 Problem: local in signature apparently unsupported Code: - signature SIG = sig structure S : sig type t end; local open S; in val x : t; end; end; = = = Error: expected END, found LOCAL Error: unbound structure name: S Error: unbound type constructor: t Error: expected EQUAL, found SEMICOLON Error: atomic expression expected, found SEMICOLON - Status: language problem: see doc/localspec --------------------------------------------------------------------------- 123. error recovery Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl Date: 18 July 1989 Version: 0.33 System: Sun3/SunOS 4.0 Problem: NJML error recovery is flakey Code: val it = () : unit - infix xxx; - fun (a xxx b) = 3; Error: expected EQUAL, found RPAREN Error: atomic expression expected, found RPAREN Error: declaration or expression expected, found RPAREN - fun output (s,w) = output s w; Error: pattern and expression in val rec dec don't agree (circularity) pattern: 'S -> 'T -> 'U expression: 'S * 'T -> 'U in declaration: output = (fn arg => (case arg of <pat> => <exp>)) - output; uncaught exception Runbind Comments: The declaration of "xxx" should be accepted - this is a minor known (?) parsing bug. The redeclaration of "output" is a user error. The two in succession seem to severely confuse the compiler; either independently seems to be OK. Status: fixed --------------------------------------------------------------------------- 124. compiler bug after incomplete qualified identifier Submitter: David Tarditi, Princeton University, drt@notecnirp Date: 4/21/89 Version: 0.33 System: Vax/4.3 BSD Problem: compiler error results when incomplete qualified identifier is used. Sample Run: Standard ML of New Jersey, Version 0.33, 1 April 1989 val it = () : unit -Integer.; Error: incomplete qualified identifier Error: Compiler bug: EnvAccess.lookPathinStr.getStr - Comments: Caused by using an incomplete qualified identifier. Status: fixed in 0.56, sort of. --------------------------------------------------------------------------- 125. constructor exported from abstype declaration Submitter: Carl Gunter <gunter@CENTRAL.CIS.UPENN.EDU> Date: 6/25/89 Version: 0.33 Problem: constructor for abstract type visible outside abstype decl Code: abstype intset = Set of int list with val empty_set = Set []; end - Set; val it = fn : int list -> intset Status: fixed in 0.39 --------------------------------------------------------------------------- 126. scope of explicit type variables Submitter: Mads Tofte <mads%lfcs.edinburgh.ac.uk@NSFNET-RELAY.AC.UK> Date: 7/11/89 Version: 0.33 Problem: New Jersey ML (Version 33) does not accept the following declarations. It complains that a user bound type variable escapes out of scope in `insert'. But the scope of ''a and 'b is the whole of the fun declaration. The problem seems to be associated with mutual recursion. type (''a, 'b)map = (''a * 'b) list fun plus(l:(''a,'b)map ,[]: (''a, 'b)map ): (''a, 'b)map = l | plus(l,hd::tl) = plus(insert(l,hd), tl) and insert([], p) = [p] | insert((x,y)::rest, (x',y')) = if x=x' then (x',y')::rest else (x,y) :: insert(rest,(x',y')); Status: fixed in 0.54 --------------------------------------------------------------------------- 127. sharing and equality types Submitter: Mads Tofte <mads%lfcs.edinburgh.ac.uk@NSFNET-RELAY.AC.UK> Date: 7/11/89 Version: 0.33 Problem: New Jersey ML does not accept the following functor declaration (it complains that S.x is not of equality type). According to the Definition, two types share only if they have the same name (stamp). In particular, since equality is an attribute of type names (Version 3, page 16), one admits equality iff the other does (one cannot have different ``views'' of equality). Presumably the problem is a bug in the unification of type names. Code: functor f(structure S : sig type t val x: t end structure T : sig eqtype t end sharing S = T )= struct val b:bool = S.x = S.x end; Status: fixed in 0.54 --------------------------------------------------------------------------- 128. question mark as reserved word Submitter: Mads Tofte <mads%lfcs.edinburgh.ac.uk@NSFNET-RELAY.AC.UK> Date: 7/11/89 Version: 0.33 Problem: New Jersey ML treats ? as a reserved word (it once was). Status: fixed in 0.54 --------------------------------------------------------------------------- 129. Bind exception parsing functor (same as 94) Submitter: Hans Bruun Department of Computer Science, Technical University of Denmark hb@iddth.dk Date: 9-June-1989 Version: 0.33 System: Vax/Ultrix Problem: parsing functor raises Bind Code: signature S_sig= sig type 'a T val fs: 'a T -> 'a T end; functor S() = struct datatype 'a T = C fun fs (x: 'a T )= C: 'a T end ; functor F (type t)= struct structure S1: S_sig= S(); open S1 type FT = t T fun ff (x : FT)= fs x end; Messages: uncaught exception Bind Comments: Without ': FT' or ': S_sig' the code is accepted by the compiler. Status: Fixed in 0.37 --------------------------------------------------------------------------- 130. compiler bug on functor application Submitter: Hans Bruun Department of Computer Science, Technical University of Denmark hb@iddth.dk Date: 24-May-1989 Version: 0.33 System: Vax/Ultrix Code: structure S = struct datatype 'a T = C fun fs (x: 'a T)= x end ; functor F (type t)= struct open S type FT = t T fun ff (x : FT)= fs x end; structure SF= F(type t=int); Messages: structure S : sig datatype 'a T con C : 'a T val fs : 'a T -> 'a T end functor F : <sig> bug.sml, line 15: Error: Compiler bug: SigMatch.applyFunctor/insttyc Status: fixed in 0.39 --------------------------------------------------------------------------- 131. dying on files of certain lengths Submitter: Jussi Rintanen, Helsinki University of Technology, jur@hutcs.hut.fi Date: 15 June 1989 Version: 0.33 1 April 1989 System: Vax 4.3 BSD, Sun-4 SunOS Release4-3.2 (?) Problem: Neither the batch compiler not the interactive system accept source files of size 2049, 4097, ...(???). Code: Tested with 2 signatures, I inserted white space, works properly if the file size is a byte lower or higher. Messages: Sun-4 dumps core, uVax raises Io Status: fixed in 0.37 --------------------------------------------------------------------------- 132. rebinding of "=" allowed Submitter: Mike Fourman (mikef%lfcs.ed.ac.uk) Date: 6/8/89 Version: 0.33 Problem: NJML allows = to be rebound (contrary to page 4 of the definition) Code: - val op = = op < : int * int -> bool; val = = fn : int * int -> bool - Status: not important --------------------------------------------------------------------------- 133. overloading resolution is weaker than Edinburgh SML or Poly ML Submitter: Larry Paulson (lcp@computer-lab.cambridge.ac.uk) Date: 5/8/89 Version: 0.33 Problem: Code: datatype 'a tree = Stree of 'a list * (string * 'a tree) list fun insert ((key::keys, x), Stree(xs,alist)) = let fun inslist((keyi,tri)::alist) = if key<keyi then alist else (keyi,tri) :: inslist alist in Stree(xs, inslist alist) end; Messages: Error: overloaded variable "<" cannot be resolved Status: fixed in 0.54 --------------------------------------------------------------------------- 134. type checking Submitter: Erik Tarnvik Department of Computing Science University of Umea SWEDEN erikt@cs.umu.se Date: 5/12/89 Version: 0.33 System: Sun3 Problem: The compiler reports a type clash were it shouldn't. Code: type 'a ft = (int * 'a) list; fun f ([]:'a ft) x = []:'a ft | f (((y,fy)::l):'a ft) x = if x = y then l:'a ft else (y,fy)::(f l x):'a ft and g (l:'a ft) (x,fx) = (x,fx) :: (f l x):'a ft; Messages: type 'a ft = (int * 'a) list line 10: Error: operator and operand don't agree (bound type var) operator domain: (int * 'aU) list operand: 'aU ft in expression: f l Comments: The Edinburgh SML (ver 3.3) does not report an error on this code. If the 'and' in the last line is changed to 'fun', no error is reported. I hope I haven't missunderstood something about SML. This is a bug, isn't it? Status: fixed in 0.49 --------------------------------------------------------------------------- 135. eqtype vs abstype Submitted: Bernard Sufrin (sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK) Date: 7/26/89 Version: 0.33 Problem: interaction of abstype and eqtype I ran into this problem whilst writing you a long note concerning abstraction bindings structure bindings and their respect for type and eqtype specifications. Here's a miniature version of the larger problem. We want a pair of types Open and Shut, and transfer functions between them. The two signatures below are candidates for describing such a structure: the latter leaves visible the equality on Open, the former should not. signature T = sig type Shut type Open val Shut:Open->Shut and Open: Shut->Open end signature U = sig type Shut eqtype Open val Shut:Open->Shut and Open: Shut->Open end Now we design a functor which simply wraps something up in order to shut it. functor absT(type Open) = struct type Open = Open abstype Shut = SHUT of Open with val Shut = SHUT fun Open(SHUT x) = x end end Now we instantiate it: structure b:T = absT(type Open=int) Compiler yields: structure b : sig eqtype Shut <----- can't be right, surely eqtype Open val Open : Shut -> Open val Shut : Open -> Shut end The equality on Shut has leaked, despite the fact that the actual representation of Shut is an abstype. (The same happens if absT is itself constrained to yield a T) - b.Shut 3=b.Shut 4; val it = false : bool On the other hand using an abstraction binding abstraction ab:T = absT(type Open=int) Compiler yields, correctly, structure ab : sig type Shut type Open val Open : Shut -> Open val Shut : Open -> Shut end but I cannot actually apply ab.Shut to an integer (its domain is not int, but an opaque and different type, namely ab.Open). Now let's try abstraction au:U = absT(type Open=int) Compiler yields, correctly, structure au : sig type Shut eqtype Open val Open : Shut -> Open val Shut : Open -> Shut end but I still can't apply au.Shut to an integer. Incidentally in my original note I asked (a) whether I ought to be able to, (b) if so, whether eqtype was not getting a bit overloaded [equality visible AND representation visible] (c) if not, how could one do this sort of thing at all? Meanwhile structure argh:U = absT(type Open=int) still makes Open and Shut both eqtypes. More bizarrely, we have abstype opaque = opaque of int with val hide = opaque val show = fn(opaque x)=>x end structure biz:T = absT(type Open=opaque) Compiler yields structure biz : sig eqtype Shut <--- wow! type Open val Open : Shut -> Open val Shut : Open -> Shut end Shut is now an eqtype despite being an abstype whose representation includes another abstype! Status: fixed in 0.54 --------------------------------------------------------------------------- 136. linkdata problem Submitter: John Reppy (ulysses!jhr, jhr@cs.cornell.edu) Date: 7/12/89 Version: 0.36 System: Sun 3, SunOS 4.0.3 Problem: failure to build Code: When I tried to build 0.36 on the sun-3, I got the message ld: : Is a directory on the load of the runtime system. The problem is with the allmo.o file. I am able to build the system using "-noshare". Status: fixed in 0.49 --------------------------------------------------------------------------- 137. profiler failure Submitter: Ian Dickinson, HP Labs, Information Systems Centre, Bristol ijd%otter@hplabs.hp.com Date: 9/28/89 Version: 0.33 System: HP 9000 HP-UX 6.3 Problem: I have a small, compute intensive program (around 2K lines of code including comments). With the profiler turned on, njml fails repeatably at the first major collect: - test 30 30; Case 30: TOLUENE, A,O-DICHLORO [Major collection... 54% used (2332228/4249436), 2483 msec] unknown signal: 20 Process SML exited abnormally with code 148 Priority: A --------------------------------------------------------------------------- 138. numeric labels not equivalent to tuples Submitter: Russ Green <rjg%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK> Date: Thu, 23 Nov 89 11:10:18 GMT Version: 0.43 Problem: numeric labels over 9 not treated properly Code: New Jersey ML seems to get confused with records composed of n numeric labels where n > 9. (Poly ML doesn't) - val a = {1=0,2=0,3=0,4=0,5=0,6=0,7=0,8=0,9=0}; val a = (0,0,0,0,0,0,0,0,0) : int * ... * int (* OK *) - val b = {1=0,2=0,3=0,4=0,5=0,6=0,7=0,8=0,9=0,10=0}; val b = {1=0,10=0,2=0,3=0,4=0,5=0,6=0,7=0,8=0,9=0} : {1:int,10:int,2:int,3:int,4:int,5:int,6:int,7:int,8:int,9:int} The resulting record type will not unify with the corresponding tuple - a = (0,0,0,0,0,0,0,0,0); val it = true : bool (* OK *) - b = (0,0,0,0,0,0,0,0,0,0); Error: operator and operand don't agree (tycon mismatch) operator domain:{1:int,10:int,2:int,3:int,4:int,5:int,6:int,7:int,8:int,9:int} * {1:int,10:int,2:int,3:int,4:int,5:int,6:int,7:int,8:int,9:int} operand: {1:int,10:int,2:int,3:int,4:int,5:int,6:int,7:int,8:int,9:int} * (int * int * int * int * int * int * int * int * int * int) in expression: b = (0,0,0,0,0,0,0,0,0,0) Comments: Presumably something to do with the sorting of the record labels (10 comes before 2)? Status: fixed in 0.54 -------------------------------------------------------------------------------- 139. compiling with gcc doesn't work Submitter: Brian Boutel, brian@comp.vuw.ac.nz Date: 9 November 1989 Version: 0.36 & later System: HP/Sun 3 Problem: compiling with gcc doesn't work Description: I have been trying again to port sml to H-P 68030 boxes running MORE/bsd, using the Gnu C compiler. We have a mix of Sun3 and H-P machines, and, although I have installed sml on the suns, it would be convenient to have it available on the H-Ps as well. The H-P port has not worked, and to separate the problems arising from the Operating System from those arising from the use of gcc, I have tried building sml on the suns with gcc (using the -traditional option). The build completes, but the resulting sml dies immediately while doing a major garbage collection. It does not get as far as announcing itself as Standard ML of ..... I have tried various options, (optimiser on/off some of the gcc -f options) without effect. Have you tried gcc? I am anxious to persue this as I think getting a gcc compiled version to run on the suns is the right first step towards porting to the H-Ps. Can you offer any suggestions? I am using sml version 0.36. ( I tried today to ftp to research.att.com to check for a later version, but found an empty directory when logging on as anonymous, and was refused permission to log on as mldist.) Changes made to the source are summarised as ------ gnu C compiler requires f68881 to be changed to m68881 Changed in makeml by introducing $CCOMP, set to GNUCC for machine hp300, otherwise "", and testing it in defining CFL for M68 ---------------- for H-P, sys/exec.h defines MID_HP300 instead of M_68020 linkdata.c and export.c have conditional code if HP300 defined makeml has to pass HP300 to make for linkdata ------------- for H-P, callgc.c has FPE_TRAPV_TRAP undefined, and TRAPV returns FPE_INTOVF_TRAP so FPE_TRAPV_TRAP is defined as FPE_INTOVF_TRAP in callgc.c ---------- _minitfp_ and _fp_state_mc68881 not defined anywhere for H-P .globl omitted if HP300 in M68.prim.s -------------------- run dies because stack clobbered by apply Registers saved ala NeXT/MACH in saveregs/restoreregs in prim.s if GNUCC Status: fixed in 0.44 -------------------------------------------------------------------------------- 140. comment to end of file (see also bug 64) Submitter: Conal Elliott, Kestrel Institute, conal@kestrel.edu Date: Wed Nov 8 11:15:35 1989 Version: 0.39 System: Sparc Problem: The compiler doesn't give an error message if the file ends in the middle of a comment. Messages: None (that's the problem) Comments: This has tripped me up a few times, and was quite puzzling. Status: fixed in 0.54 -------------------------------------------------------------------------------- 141. interrupting gc dumps core Submitter: peter@central.cis.upenn.edu (Peter Buneman) Date: 18 November 1989 Version: 0.39 System: ?? Problem: I've found occasions on which our current version of ML goes a bit flakey after being interrupted during garbage collection. I haven't been able to pin it down until now. The following interactive session appears to be repeatable. Code: % sml Standard ML of New Jersey, Version 0.39, 8 September 1989 val it = () : unit - fun foo() = 1::foo(); val foo = fn : unit -> int list - foo(); [Major collection... [Increasing heap to 7144k] 70% used (1752720/2487664), 4810 msec] [Increasing heap to 7280k] [Major collection... 62% used (2484132/3975316), 7580 msec] *** I typed <cntrl>C during this garbage collection [Increasing heap to 11648k] uncaught exception Interrupt - fun bar() = bar(); val bar = fn : unit -> 'a - bar(); *** I did not type <cntrl>C here !! uncaught exception Interrupt - bar(); *** nor here!! uncaught exception Interrupt - Comments: In 0.43d2 I can't repeat this behavior, but interrupting during gc causes a bus error or segmentation fault. [dbm] Status: fixed in 0.54 -------------------------------------------------------------------------------- 142. import incompatible with interpreter only image Submitter: Bernard Sufrin <sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK> Date: 27 Sept 1989 Version: 0.39 System: Sun 3 ? Problem: import into interpreter Description: OK; when making the intepreter-only it seems one must: makeml -noshare -noclean -run makeml -ionly -noshare -norun Then one gets the smaller (by about 200k) file. Problem: it is not possible to import precompiled stuff; the compiler decides that the .bin file is not in the right format; tries to recompile, and fails for lack of a code generator. Here's an example... - import "/prg/pl/sml/lib/lex"; [reading /prg/pl/sml/lib/lex.bin... ] [/prg/pl/sml/lib/lex.bin is the wrong format; recompiling] [closing /prg/pl/sml/lib/lex.bin] [reading /prg/pl/sml/lib/lex.sml] [reading /prg/pl/sml/lib/lib/lib/extend.bin... ] [/prg/pl/sml/lib/lib/lib/extend.bin is the wrong format; recompiling] [closing /prg/pl/sml/lib/lib/lib/extend.bin] [reading /prg/pl/sml/lib/lib/lib/extend.sml] /prg/pl/sml/lib/lib/lib/extend.sml, line 52: Error: Compiler bug: no code generator! [closing /prg/pl/sml/lib/lib/lib/extend.sml] [closing /prg/pl/sml/lib/lex.sml] IMPORT failed (compile-time exception: Syntax) When trying to reproduce the import bug you might try making the dependency graph more than three arcs deep. Comments: Obviously we don't want to have to dispense with import when using the intepreter-only (typically it'd be students loading precompiled libraries), but I presume we don't want the complication of lambda-formatted bin files as well as machine code bin files. May I propose the following: import from an ionly system should behave like import in the cg system if everything is up-to-date. if something is out of date, then import should either abort, or behave like use (I prefer the latter, I think, but you might make it controllable from a System.Control variable). Status: not important -------------------------------------------------------------------------------- 143. use failes on certain input files of a certain length Submitter: Jawahar Malhotra (malhotra%metasoft.uucp@BBN.COM) Date: 26 October 1989 Version: ?? System: ?? Problem: use dumping core on magic input file length Description: I have a source file which contains a signature definition and a functor definition. When I load it using the "use" statement, the compiler responds with the signature defn and the functor defn but then dumps core just before its prints the [<closing file>] line. Strangely, if I add another blank line to the file, everything is OK. If you like, I can mail you the file; please let me know if you would like the file. Here is a reproduction of the compiler's output: - use "oareadattr.sml"; [opening oareadattr.sml] signature OAREADATTR = ... ... ... end functor OAReadAttrFun : <sig> Segmentation Fault (core dumped) Comments: Status: not reproducible; possibly fixed. -------------------------------------------------------------------------------- 144. not waiting for child process Submitter: Jawahar Malhotra, Meta Software; malhotra%metasoft@bbn.com Date: 20 Oct 89 Version: 0.33 System: SUN OS 3.5 Problem: njsml doesn't wait for child process (created by a call to execute) to terminate. Suppose I execute the following sml stmt: - execute "ls /users/malhotra"; njsml creates a child process in which it runs ls. When ls is done, it does an exit(0). In order for the exit to complete, its parent process (njsml in this case) should do a wait(). However, njsml doesn't do this and hence the "ls" process blocks on its exit and remains until njsml exits. The state of this process (as displayed by "ps") is: malhotra 2376 0.0 0.1 0 0 p2 Z 0:00 <exiting> Comments: One fix would be to prevent the process created by "execute" from being njsml's child. In this case, njsml would not have to wait to collect the child's termination status. This can be done by forking twice. Hence the code for execute might look like: (assume njsml is process p1) ------------------------------------------------------------ /* in process p1 */ if (fork() == 0) { /* in p2 */ if (fork() == 0) { /* in p3 */ ......... execl(......); ....... } else { /* in p2 */ exit(0); } } /* in p1 */ wait(0); /* wait for p2 to exit */ ------------------------------------------------------------ Another fix (maybe easier to implement) is to install a signal handler for SIGCHLD. signal(SIGCHLD, ack); where ack() is simply: ack() { wait(0); } Status: not a bug -------------------------------------------------------------------------------- 145. stale top-level continuations cause type bugs Submitter: Andrzej Filinski, CMU Computer Science (andrzej@cs.cmu.edu) Date: Oct 11, 1989 Version: 0.39 (8 September 1989) System: Sun3/4.3BSD Problem: Capturing top-level continuation messes up the type system Code: val cl = ref([]:int cont list); callcc (fn k=>(cl:=[k]; 42)); val u = throw (hd (!cl)) 65; (* value 65 with universal type! *) u+1; (* u as integer *) u^"str"; (* u as string *) u:bool; (* u as boolean (cannot print) *) u:real; (* u as real (core dump) *) Comments: This may be a tricky problem, i.e. it is not quite clear what the "right" behavior should be when the top-level continuation is captured and carried across commands. Please don't take this as a criticism of callcc/throw in general, though; they're great! Any plans for integrating them more deeply in the language, like exceptions? Status: fixed in 0.49 -------------------------------------------------------------------------------- 146. inputting 1025 characters fails Submitter: Jawahar Malhotra, Meta Software, malhotra%metasoft@bbn.com Date: 9/29/89 Version: 0.33 System: Sun3/SunOS 3.5 Problem: "input" when applied to std_in and an int > 1024 returns "". Code: - input std_in 1025; > val it = "" : string Comments: It obviously works for all other kinds of instreams. Status: fixed in 0.43 -------------------------------------------------------------------------------- 147. compiler blowup Submitter: Ian Dickinson, HP Labs, Information Systems Centre, Bristol ijd%otter@hplabs.hp.com Date: 27 Sept 1989 Version: 0.33 System: HP 9000 HP-UX 6.3 Problem: compiler out to lunch Description: I have a large-ish list of type: (string * string list) list It has 1003 entries, and on average the string list in each pair is around 3 elements. Each string is between 5 and 9 characters. The list is declared in a file in the form: val graph = [ ("foo", ["bar"]), ... etc ...]; This is the only declaration in the file. Poly-ml compiles the file in about 10 seconds. Njml takes around an hour to increase the heap to 30Mbytes, performs several major collects, and then bombs with an out-of-memory error. Status: fixed in 0.43 -------------------------------------------------------------------------------- 148. relational operators on empty string Submitter: jhr@cs.cornell.edu (John Reppy) also Erik Tarnvik, University of Umea, SWEDEN (erikt@cs.umu.se) Date: 14 Sept 1989 Version: 0.39? Problem: The implementation of "<" on strings doesn't work for ("" < ""). Comments: The fix is to replace line 835 of boot/perv.sml, which is fun sgtr(_,"") = true with the lines fun sgtr("","") = false | sgtr(_,"") = true Status: fixed in 0.43 -------------------------------------------------------------------------------- 149. infinite gc loop with insufficient swap space Submitter: jhr@cs.cornell.edu (John Reppy) Date: 18 Sept 89 Version: 0.39 System: Vax Problem: SML/NJ is being used at Cornell for a course this semester, and we've run into a problem with it on multi-user vaxen. If there isn't sufficient swap space for the system to run, it seems to get into an infinite loop of garbage collection attempts. I should fail gracefully in this situation. Status: this is a long, finite loop; not a bug -------------------------------------------------------------------------------- 150. incomplete sharing spec accepted Submitter: Simon Finn <simon%abstract-hardware-ltd.co.uk@NSFnet-Relay.AC.UK> Date: 13 Sept 89 Version: 0.33 Problem: Both NJML (v0.33) and Poly/ML (v1.80x) erroneously parse the following: signature SIG = sig type t sharing type t end; Comments: The above signature is illegal, since sharing constraints must involve at least two types / structures ("n >= 2" in section 3.5, figure 7). This bug was found by Mike Crawley. Status: fixed in 0.54 -------------------------------------------------------------------------------- 151. can't limit length of list printed Submitter: Lawrence C Paulson <lcp%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK> Date: 14 Sept 1989 Version: ?? Problem: How do you tell New Jersey ML not to print all the elements of a list? System.Control.Print.printDepth seems to consider nesting only. Code: - take(100,ms); val it = [1861294,62685628,105212158,14112418,78287461,35512822,180290056,316473 64,72270388,168319897,212829007,43941079,142303594,174252739,117587239,56623288, 96050461,46119052,152678905,140061256,13973941,209088847,109015732,167261566,142 82215,159257329,69147538,162991570,121739197,19339324,52452037,18146911,23268574 ,183534766,93272557,163056892,193407172,50009149,131379349,28143469,114167002,14 8862536,85731877,182107423,28619248,67440382,145320439,121674259,172092145,16412 2099,196052140,141367123,32002813,17851816,198701119,46866244,196351819,12166451 8,163288573,14499193,10976578,64526104,139008271,417145,67962574,64746709,994460 5,117181366,115999456,124879621,188830621,158322193,82998094,187333183,178599706 ,158794345,17054389,62405431,142521907,182072470,22294474,162171034,163367647,12 3860254,25498117,13136599,105899185,53939356,184226566,191249065,66913411,177659 797,114495331,28730221,76001191,104114101,180588016,60920215,151887592,208100422 ] : int list - [[[[[[[[[[[4]]]]]]]]]]]; val it = [[[[[#]]]]] : int list list list list list list list list list list list - Status: fixed in 0.54 -------------------------------------------------------------------------------- 152. floating point errors Submitter: Lawrence C Paulson <lcp%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK> Date: Thu, 14 Sep 89 Version: ?? Problem: Why cannot New Jersey handle integers that are well within the maximum available on the hardware? Code: - exp(31.0 * ln 2.0); val it = 2147483648.0 : real - floor 2000000000.0; uncaught exception Floor Status: fixed in 0.54; but the maximum integer is 1073741823 in SML-NJ -------------------------------------------------------------------------------- 153. interrupting coroutine loop dumps core Submitter: Bernard Sufrin <sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK> Date: Sep 15 11:14:13 1989 Version: 0.43 System: Sun 3 Problem: producer consumer segementation fault interrupt consumer(producer) with a single ^c to cause a segmentation fault Code: datatype state = S of state cont; fun resume(S k: state) : state = callcc( fn k':state cont => throw k (S k')) fun initiate(p:state -> unit) = callcc( fn k : state cont => (p(S k); S k)) val buf = ref 0; fun producer(s:state):unit = let val n=ref 0 val ccont : state ref = ref(resume s) in while true do (inc n; buf := !n; ccont := resume(!ccont)) end fun consumer(prod: state->unit) : unit = let val pcont = ref(initiate prod) in while true do (pcont := resume(!pcont); print (!buf)) end Status: fixed in 0.56 -------------------------------------------------------------------------------- 154. import smashing memory Submitter: Benjamin Pierce, CMU (bcp@cs.cmu.edu) Date: 11/34/89 Version: 0.41 System: Sun3/SunOS 3.5.2 Problem: import seems to be smashing memory Comments: I've included a minimal version of program that exercises this bug on my machine. Slightly different versions give different incorrect results, or simply fail with bus errors. Removing the first line of tconst.sml (the import of globals, which is never used here) gives the correct answer. Transcript: Standard ML of New Jersey, Version 0.41, 25 October 1989 val it = () : unit - use "main.sml"; [opening main.sml] val it = () : unit [reading checker.sml] [reading tconst.sml] [reading globals.sml] [closing globals.sml] [writing globals.bin... done] [closing tconst.sml] [writing tconst.bin... done] [closing checker.sml] [writing checker.bin... done] signature GLOBALS signature CHECKER signature TCONST functor TConstFun : <sig> functor GlobalsFun : <sig> functor CheckerFun : <sig> structure TConst val it = "\000\^VG\200" : ?.t <--- Should be "int" [closing main.sml] val it = () : unit - Code: (* ------------------------ globals.sml: ---------------------- *) signature GLOBALS = sig val member: ''a -> ''a list -> bool end functor GlobalsFun() : GLOBALS = struct fun member x [] = false | member x (y::l) = (x=y) orelse (member x l) end (* ------------------------ tconst.sml: ---------------------- *) import "globals"; signature TCONST = sig type t val from_string: string -> t end functor TConstFun((*structure Globals:GLOBALS*)): TCONST = struct exception IllegalTConst of string type t = string fun member x [] = false | member x (y::l) = (x=y) orelse (member x l) fun from_string s = if not (member s ["int", "real", "bool"]) then raise IllegalTConst(s) else s end (* ------------------------ checker.sml: ---------------------- *) import "tconst"; signature CHECKER = sig end (* CHECKER *) functor CheckerFun() : CHECKER = struct end (* CheckerFun *) (* ------------------------ main.sml: ---------------------- *) System.Control.Print.signatures := false; import "checker"; (* structure Globals:GLOBALS = GlobalsFun(); *) structure TConst:TCONST = TConstFun((*structure Globals=Globals*)); TConst.from_string "int"; Status: fixed in 0.49 -------------------------------------------------------------------------------- 155. Compiler bug caused by of missing structure Submitter: Benjamin Pierce (bcp@cs.cmu.edu) Date: 11/3/89 Version: 0.52 System: Sun3/SunOS Problem: Missing structure component shows up later as compiler bug Transcript: - use "bug155.sml"; bug155.sml:16.1-18.3 Error: unmatched structure spec: A Error: Compiler bug: TypesUtil.lookTycPath.2 Code: (bug155.sml) signature S1 = sig type t end; signature S2 = sig structure A : S1 val x : A.t end; structure B : S2 = struct val x = 3 end; Status: fixed in 0.54 -------------------------------------------------------------------------------- 156. confusing parser error message Submitter: dbm Date: 4 Nov 1989 Version: 0.43 Problem: Misspelled constructor (VALbind instead of VARbind) in line | scan ((VALbind _)::_) = ... causes inappropriate message: basics/typesutil.sml, line 74: Error: identifiers in clauses don't match Status: fixed in 0.49 -------------------------------------------------------------------------------- 157. nested imports corrupt memory (same as 154?) Submitter: sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK Date: 3 Nov 89 Version: 0.39 System: Sun 3 Problem: I have had a good deal of trouble with transitive imports. Symptom is segmentation failure on first call of a procedure defined in a functor imported transitively. parser: defines abstractsyntax, lexer, and parser functors codegen: imports parser defines code generator main: imports codegen instantiates abstractsyntax, lexer, parser crashes at first invocation of procedure defined in parser. When I remove the "import parser" from codegen, and import it directly from main, then all is well. This actually arose in a student's system, and I haven't time to try it in smaller contexts. Does the symptom sound familiar? If not, I can send the whole lot to you. Status: fixed in 0.49 -------------------------------------------------------------------------------- 158. sparc code generator problem Submitter: Dale Miller, UPenn, dale@linc.cis.upenn.edu Date: 22 Oct 89 Version: 0.39 System: Sun4 (unagi.cis.upenn.edu) Problem: Error: Compiler bug: [SparcCoder.move] Code: /pkg/ml.39/lib/lexgen/lexgen.sml Transcript: Standard ML of New Jersey, Version 0.39, 8 September 1989 val it = () : unit - use "/pkg/ml.39/lib/lexgen/lexgen.sml"; [opening /pkg/ml.39/lib/lexgen/lexgen.sml] /pkg/ml.39/lib/lexgen/lexgen.sml, line 1083: Warning: match not exhaustive (nil,nil) => ... (a :: a',b :: b') => ... /pkg/ml.39/lib/lexgen/lexgen.sml, line 1083: Warning: match not exhaustive 1 => ... 2 => ... 3 => ... /pkg/ml.39/lib/lexgen/lexgen.sml, line 1083: Warning: match not exhaustive (tl,el) :: r => ... [Major collection... 68% used (1443980/2116924), 2760 msec] [Increasing heap to 4576k] [Major collection... 70% used (1724168/2441672), 3170 msec] [Increasing heap to 5520k] [Major collection... 88% used (2573912/2923048), 4620 msec] [Increasing heap to 8040k] [Major collection... 57% used (2395752/4198108), 4320 msec] [Major collection... 68% used (2819788/4139960), 5060 msec] [Increasing heap to 8368k] [Major collection... 78% used (3364372/4305528), 5940 msec] [Increasing heap to 10080k] /pkg/ml.39/lib/lexgen/lexgen.sml, line 1083: Error: Compiler bug: [SparcCoder.move] ?exception Syntax in SparcCM.storeindexl [closing /pkg/ml.39/lib/lexgen/lexgen.sml] - Status: fixed in 0.43 -------------------------------------------------------------------------------- 159. nested structure reference causes compiler bug Submitter: Tom Murtagh, Rice University, tpm@rice.edu Date: 10/20/89 Version: 0.38 and 0.39 System: Sun4/SunOS 4.0.3c and Sun3/SunOS 4.0.? Problem: Compiler dies on reference to type from a nested structure Description: I ran into another problem with the compiler. This one does not appear to have anything to do with the port to SPARC. I ran it on a Sparcstation using verion 0.38 and on a Sun3 running version 0.39 (Bruce's copy) and it died on both. It compiled without complaint on a Sun 3 running verions 0.33 (which is installed in the public local software directory here). Code: (smaller.sml = /usr/sml/bugs/code/bug.159) signature SYMTAB = sig type ident end signature LEX = sig structure Symtab : SYMTAB datatype lexeme = ID of Symtab.ident | DELIM end structure Symtab = struct type ident = string end functor lex( symtab : SYMTAB ) = struct structure Symtab : SYMTAB = symtab datatype lexeme = ID of Symtab.ident | DELIM end structure Lex : LEX = lex( Symtab ) Transcript: % sml Standard ML of New Jersey, Version 0.38, 23 August 1989 val it = () : unit - use "smaller.sml" = ; [opening smaller.sml] signature SYMTAB = sig type ident end signature LEX = sig structure Symtab : sig...end datatype lexeme con DELIM : lexeme con ID : Symtab.ident -> lexeme end structure Symtab : sig eqtype ident end functor lex : <sig> structure Lex : sig structure Symtab : sig...end datatype lexeme con DELIM : lexeme con ID : smaller.sml, line 31: Error: Compiler bug: TypesUtil.lookTycPath. 1 [closing smaller.sml] Status: fixed in 0.43 -------------------------------------------------------------------------------- 160. errorty fails to match sig spec Submitter: dbm Date: 18 Oct 89 Version: 0.43 System: Sun 3 Problem: error type not matched in checking signature spec Messages: typing/functor.sml, line 363: Error: value type in structure doesn't match signature spec name: abstractBody spec: Structure * stampsets -> Structure actual: Structure * error -> Structure Status: fixed in 0.54 -------------------------------------------------------------------------------- 161. nested functor calls Submitter: Don Sannella <dts%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK> Date: Tue, 17 Oct 89 18:29:27 BST Version: 0.39 System: Sun 3 Problem: nested functor calls broken Code: signature SIG = sig type t end; functor F(X : SIG) : SIG = struct type t = X.t end; (* Replacing output signature by its definition: no problem *) functor F'(X : SIG) : sig type t end = struct type t = X.t end; functor G(X : SIG) : SIG = struct type t = X.t end; functor H(X : SIG) : SIG = G(F(X)); (* Replacing output signature by its definition: fails with exception Bind *) functor H'(X : SIG) : sig type t end = G(F(X)); signature SIG = sig type t end; functor F(X : SIG) : SIG = struct type t = X.t end; (* Replacing output signature by its definition: no problem *) functor F'(X : SIG) : sig type t end = struct type t = X.t end; functor G(X : SIG) : SIG = struct type t = X.t end; functor H(X : SIG) : SIG = G(F(X)); (* Replacing output signature by its definition: fails with exception Bind *) functor H'(X : SIG) : sig type t end = G(F(X)); Status: fixed in 0.43 -------------------------------------------------------------------------------- 162. ByteArray subscript exception expected Submitter: Jawahar Malhotra, Meta Software Corp., malhotra%metasoft@bbn.com Date: 10/17/89 Version: 0.33 System: Sun OS 3.5 Problem: ByteArray.extract doesn't raise Subscript exception when I think it should. Code: val ba = ByteArray.array(4,0); (* I feel that the following SHOULD raise an exception *) ByteArray.extract(ba,4,0); (* the following two statements CORRECTLY raise exceptions *) ByteArray.extract(ba,5,0); ByteArray.sub(ba,4); Status: not a bug -------------------------------------------------------------------------------- 163. function definition syntax Submitter: Andy Gordon, Cambridge University, adg@cl.cam.ac.uk Date: Mon Oct 16 15:26:44 1989 Version: Version 0.33, 1 April 1989 System: Sun Problem: another strange function definition Code: fun cps-fact n k = cps-fact n k; Messages: Error: Compiler bug: generalizeTy -- bad arg fact : 'S -> 'T -> undef Comments: Like in bug 73, I was mistakenly trying to define a function whose identifier contained a hyphen, but this time the compiler complains of a Compiler bug. Status: fixed in 0.54 -------------------------------------------------------------------------------- 164. NS32 in makeml Submitter: Allan E. Johannesen, wpi, aej@wpi.wpi.edu Date: 13-Oct-1989 Version: 0.39, maybe. That was the number in the README System: Encore Problem: makeml error Code: makeml -encore Messages: makeml: must specify machine type Comments: please put NS32 in $MACHINE case of makeml maybe: NS32) if test "$OPSYS" != BSD then echo "makeml: bad os ($OPSYS) for encore" exit 1 fi if test -z "$MO" then MO="../mo.encore" fi MODULE="$MODULEKIND"Encore ;; Status: no support for NS32, unfortunately -------------------------------------------------------------------------------- 165. NS32 problem in export.c Submitter: Allan E. Johannesen, wpi, aej@wpi.wpi.edu Date: 13-Oct-1989 Version: 0.39, maybe. That was the number in the README System: Encore Problem: compile error Code: makeml -encore Messages: "export.c", line 108: Undefined member: a_syms Comments: please change: #ifndef NS32 E.a_syms = 0; #endif NS32 E.a_syms = 0; to: #ifndef NS32 E.a_syms = 0; #endif NS32 Status: no support for NS32, unfortunately -------------------------------------------------------------------------------- 166. sparc code generator Submitter: Konrad Slind <slind%calgary.cdn@relay.CDNnet.CA> (also Soren Christensen, Aarhus, schristensen@daimi.dk) Date: 13 Oct 89 0:52 -0600 Problem: On the Sparcstation 1, under SunOS 4.0.3c, I get the following error: $ sml4 Standard ML of New Jersey, Version 0.39, 8 September 1989 val it = () : unit - val z = ref " "; val z = ref " " : string ref - z := " "; Error: Compiler bug: [SparcCoder.move] ?exception Syntax in SparcCM.storeindexl - z := "\n"; Illegal instruction - core dumped $ On just a regular old Sun4, under SunOS 4.0.3_Export, the above runs correctly. Status: fixed in 0.43 -------------------------------------------------------------------------------- 167. repeated bound type variables in type declaration Submitter: Nick Rothwell Date: 5 Oct 89 Version: 0.39? System: Sun 3 Problem: multiple binding occurences of type variable accepted Code: - datatype ('a, 'a, 'a) T = A of 'a | B of 'a; datatype ('a,'b,'c) T con A : 'a -> ('a,'b,'c) T con B : 'a -> ('a,'b,'c) T Status: fixed in 0.54 -------------------------------------------------------------------------------- 168. profiling on sparc Submitter: Tom Murtagh ( tpm@rice.edu) Date: Oct 4, 1989 Version: 0.38 System: Sun4/SunOS 4.0.3c Problem: unhandled exception Match in codegenerator when Profiling enabled I stumbled across what appears to be another problem in the Sparc code generator. It seems to fail when any function is compiled with profiling enabled. This time I do have a minimal code fragment: % sml Standard ML of New Jersey, Version 0.38, 23 August 1989 val it = () : unit - System.Control.Profile.profiling := true; val it = () : unit - (fn x => x); ?exception Match in SparcCM.storeindexl uncaught exception Match Status: fixed in 0.43 (?) -------------------------------------------------------------------------------- 169. inferring eqtypes in signatures Submitter: Randy Pollack <rap%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK> Date: Wed, 27 Sep 89 Problem: NJML (V0.39) is too liberal in inferring eqtypes in signatures Code: - functor F() = struct abstype t = E with val mk_t = E end end; functor F : <sig> - structure f = F(); structure f : sig eqtype t (*** incorrect ***) val mk_t : t end however: - structure f = struct abstype t = E with val mk_t = E end end; structure f : sig type t (*** correct ***) val mk_t : t end Priority: A Status: fixed in 0.52 -------------------------------------------------------------------------------- 170. error in makeml script Submitter: sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK Date: Wed Sep 27 Transcript: 26 % makeml -sun3 -ionly -o smli -m 3 (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s rm -f mo ln -s ../mo.m68 mo (cd runtime; rm -f run allmo.o) (cd runtime; make MACHINE=M68 linkdata) cc -O -DM68 -o linkdata linkdata.c runtime/linkdata [runtime/IntNull.mos] > runtime/allmo.o (cd runtime; make MACHINE=M68 'DEFS= -DSUN3 -DSUN3 -DBSD' 'CFL=-n -Bstatic -f68881' 'ASMBLR=as') cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c run.c cc: Warning: Obsolete option -B cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c gc.c cc: Warning: Obsolete option -B cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c callgc.c cc: Warning: Obsolete option -B /lib/cpp -DM68 -DSUN3 -DSUN3 -DBSD M68.prim.s > prim.s as -o prim.o prim.s cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c prof.c cc: Warning: Obsolete option -B cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c export.c cc: Warning: Obsolete option -B cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c objects.c cc: Warning: Obsolete option -B cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c cstruct.c cc: Warning: Obsolete option -B cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c trace.c cc: Warning: Obsolete option -B cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -o run run.o gc.o callgc.o prim.o prof.o export.o objects.o cstruct.o trace.o allmo.o cc: Warning: Obsolete option -B _Loader: ld: allmo.o: multiply defined *** Error code 2 make: Fatal error: Command failed for target `run' echo (System.Control.interp := true; exportML "smli"; output std_out System.version; output std_out "\n"); | runtime/run -m 3 -r 20 -h 2048 IntNull makeml: runtime/run: cannot execute Status: fixed (or else, old version of SunOS went away) -------------------------------------------------------------------------------- 171. illegal datatype declaration accepted Submitter: Russ Green <rjg%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK> Date: Tue, 26 Sep 89 Problem: New Jersey ML (version 0.39) accepts the following (illegal) declaration: datatype t = C1 | C1 of int (rule (30) of the version 3 language definition prohibits any two constructors from having the same identifier) Priority: A Status: fixed in 0.52 -------------------------------------------------------------------------------- 172. functor subscript error Submitter: Simon Finn <simon%abstract-hardware-ltd.co.uk@NSFnet-Relay.AC.UK> Date: Tue, 26 Sep 89 Problem: The following fragment breaks NJML (v0.39) signature SIG1 = sig type s end; signature SIG2 = sig type t val x : t structure Sub : sig val f : t -> t end; end; functor F (structure Struct1 : SIG1 structure Struct2 : SIG2) = struct val fx = Struct2.Sub.f Struct2.x; end; Messages: = = = Error: operator and operand don't agree (tycon mismatch) operator domain: ?.t operand: ?.t in expression: f x = Error: Compiler bug: abstractType Comment: Almost any perturbation of the above seems to make the bug disappear, e.g. (1) removing "structure Struct1 : SIG1" (2) or removing "type s" from SIG1 (3) or taking "f" out of "Sub" and putting it at the top level of "Struct2" [dbm] behavior is different under 43d2. It produces a lookTycPath subscript exception. Priority: A Status: fixed in 0.52 -------------------------------------------------------------------------------- 173. Runbind Submitter: Andrew Tolmach (apt@princeton.edu) Date: 31 Aug 89 Version: ... 0.43 Problem: - val s = t; Error: unbound variable t - val s = t; Error: unbound variable t - s; uncaught exception Runbind Priority: A Status: fixed in 0.52 -------------------------------------------------------------------------------- 174. import and types Submitter: Lars Bo Nielsen, Aalborg University, Strandvejen 19, 9000 Aalborg, DENMARK. Email : lbn@iesd.auc.dk Date: Dec. 4 - 1989 Version: 0.43 System: Sun 3/260 -- SunOs 4.0.1 Sun Sparc -- SunOs 4.0.3c Severity: I think this is VERY critical. Problem: Types of values in Functors is treated differently when imported and used. (Sorry hard to explain, see Code and Transcript). My code that compiled without problem with version 0.42, DIDN't compile under 0.43. Code: Refered to as file: pop.sml ================================= signature ASig = sig datatype POP = a | b end signature BSig = sig structure DT : ASig val f : DT.POP -> unit end functor AFun () : ASig = struct datatype POP = a | b end functor BFun (structure DT : ASig) : BSig = struct structure DT = DT open DT val f = fn _ => output std_out "Is Running\n" end Transcript: NOTE "<--" are my notes =================================== Standard ML of New Jersey, Version 0.43, 27 November 1989 val it = () : unit - use "pop.sml"; [opening pop.sml] <-- USE the file signature ASig = sig datatype POP con a : POP con b : POP end signature BSig = sig structure DT : sig...end val f : DT.POP -> unit end functor AFun : <sig> functor BFun : <sig> [closing pop.sml] val it = () : unit - structure A = AFun(); structure A : sig datatype POP con a : ?.POP con b : ?.POP end - structure B = BFun ( structure DT = A); structure B : sig structure DT : sig...end val f : A.POP -> unit <--- A.POP -> unit end - open A; type POP = POP - val test = a; val test = a : POP - B.f test; Is Running val it = () : unit - - - - import "pop"; [reading pop.bin... done] <--- IMPORT the file signature ASig = sig datatype POP con a : POP con b : POP end signature BSig = sig structure DT : sig...end val f : DT.POP -> unit end functor AFun : <sig> functor BFun : <sig> - structure A = AFun(); structure A : sig datatype POP con a : ?.POP con b : ?.POP end - structure B = BFun ( structure DT = A); structure B : sig structure DT : sig...end val f : ?.POP -> unit <-- ?.POP -> unit end - open A; type POP = POP - val test = a; val test = a : POP - B.f test; Error: operator and operand don't agree (tycon mismatch) operator domain: ?.POP operand: POP in expression: B.f test - Comments: I changed yesterday (Dec 3) from 0.42 to 0.43, and I have been trying all day (Dec 4) to solve my problem, until I made the little test above. During the solving periode I also had a lot of: ../file, line xxx: Error: structure sharing violation In that periode I was using "import", not "use". These error messages may show up to be caused by the same bug. Fix: Sorry, I'm not able to fix it. But I hope my example have given you enough input to track down the bug. Status: fixed in 0.53 ------------------------------------------------------------------------------ 175. redundant module loading Submitter: Tom Gordon, thomas@gmdzi.uucp Date: 6 Mar 90 Version: 0.44 System: Sparc, Sun OS Severity: minor Problem: The module loader reloads functors and signatures which have already been loaded. This drastically slows down the edit, test, debug cycle. Shouldn't only those modules be reloaded which depend on files which have been, or need to be, recompiled? Status: a wish, not a bug (desideratum for sourcegroups) ------------------------------------------------------------------------------ 176. include and sharing Submitter: Nick Date: 2/26/90 Version: 0.44 Problem: Poly/ML accepts the following, New Jersey ML (44a) rejects it: signature INCLUDE_1 = sig type Ty val x: Ty end signature INCLUDE_2 = sig type Ty val y: Ty end signature BOTH = sig type T include INCLUDE_1 sharing type Ty = T include INCLUDE_2 sharing type Ty = T end functor F(Both: BOTH) = struct val _ = [Both.x, Both.y] end; Comment: exact semantics of include not yet defined Status: not a bug -------------------------------------------------------------------------------- 177. clinkdata on sun 3 Submitter: Dave Date: 3/8/90 Version: 0.52 System: Sun3, SunOS 4.0.1 Problem: clinkdata doesn't work Transcript: nun% makeml -sun3 -sunos -noclean rm -f mo ln -s ../mo.m68 mo (cd runtime; rm -f run allmo.o) (cd runtime; make -f Makefile MACHINE=M68 'DEFS= -DSUN3 -DBSD' clinkdata) cc -g -DM68 -DSUN3 -DBSD -o clinkdata clinkdata.c runtime/clinkdata [runtime/IntM68.mos] as: error (runtime/allmo.s:4): Invalid op-code (cd runtime; make -f Makefile MACHINE=M68 'DEFS= -DSUN3 -DBSD' 'CFL=-n -Bstatic -f68881' 'ASMBLR=as' 'WARNPRIM=@:') cc -g -n -Bstatic -f68881 -DM68 -DSUN3 -DBSD -o run run.o gc.o callgc.o M68.dep. o prim.o prof.o export.o objects.o cstruct.o errstrings.o allmo.o ld: allmo.o: bad string table index (pass 1) *** Error code 4 make: Fatal error: Command failed for target `run' echo ( exportML "sml"; output std_out System.version; output std_out (chr 10) (* newline *)); | runtime/run -m 4096 -r 20 -h 2048 IntM68 makeml: runtime/run: not found Status: fixed in 0.56 -------------------------------------------------------------------------------- 178. Missing NS32.dep.c, NS32k port not working -------------------------------------------------------------------------------- 179. compiler bug (783 in sigmatch) Submitter: John Reppy Date: 2/15/90 Version: 0.51 Transcript: - structure A = GG(); (* GG is unbound *) std_in:1.16-1.17 Error: unbound functor identifier: GG Error: Compiler bug: 783 in sigmatch Comments: Have to create bogus functor Status: fixed in 0.56 -------------------------------------------------------------------------------- 180. "sharing violation" error messages not informative Submitter: Nick Date: 2/15/90 Version: 0.44 Problem: ... the diagnostic messages for sharing mismatches are not really useable: having a single message "structure sharing violation" for 100 lines of nested functor applications is no use, and I often have to recompile the entire system in Poly/ML just to get more verbose diagnostics with the context of the offending functor application and the names of the offending structures/types. Status: fixed before 0.65 -------------------------------------------------------------------------------- 181. 8-bit characters not supported in strings Submitter: Fritz Ruehr (krf@dip.eecs.umich.edu) Date: 2/8/90 Version: 0.44 Problem: I am looking to read in 8 bit characters in SML-NJ. I can get UNIX to pass 8 bits back & forth, and SML-NJ will PRINT strings containing escaped "8-bit characters" (i.e., \nnn) as honest 8-bit output, but for the life of me I cannot get it to READ 8-bit characters when i put them in a string (I get an "Ord exception"). Is this intended behavior? Is there any workaround (say, a switch I didn't notice?)? Status: fixed in 0.54 -------------------------------------------------------------------------------- 182. uncaught exception after exportFn Submitter: Andy Koenig Date: 1/31/90 Version: 0.49 (still in 0.52) Problem: Unwanted uncaught exception message printed after exportFn is called. Messages: Standard ML of New Jersey, Version 0.49, 26 January 1990 val it = () : unit - fun hello _ = print "hello world\n"; val hello = fn : 'a -> unit - exportFn ("a.out", hello); [Major collection... 98% used (492360/498444), 3900 msec] [Major collection... 2% used (13020/494516), 100 msec] [Decreasing heap to 254k] uncaught exception SystemCall with "closed outstream" Comments: this can be cosmetically improved, but resumption after an exportFn is not expected to be implemented Status: fixed in 0.59 ------------------------------------------------------------------------------ 183. "raise" not synchronized with evaluation sequence Submitter: Andrzej Filinski <andrzej@cs.cmu.edu> Date: Jan 20, 1990 Version: 0.44, 4 December 1989 System: VAX, 4.3 BSD (also Sun 3, 4.3 BSD) Severity: minor Problem: "raise" not properly synchronized to expression row evaluation Code: (raise e, s := 2); Transcript: - exception e; exception e - val s = ref 0; val s = ref 0 : int ref - (s := 1, raise e); uncaught exception e - s; val it = ref 1 : int ref [OK, did assignment first] - (raise e, s := 2); uncaught exception e - s; val it = ref 2 : int ref [did not raise e immediately] - Comments: This is pathological code, but the Standard does specify left-to-right evaluation of expression row components. Status: fixed (in 0.50?) ------------------------------------------------------------------------------ 184. bindings introduced by open are not printed Submitter: Andy Koenig Date: 1/30/90 Version: 0.52 Problem: After a top level open, the bindings introduced are not printed Comment: may provide a separate capability for requesting printing of signatures and other static info. Status: not a bug -------------------------------------------------------------------------------- 185. exportML size Submitter: Soren Christensen, University of Aarhus, Computer Science Dep., Denmark schristensen@daimi.dk Date: 24 jan 90 Version: 0.44 System: Sun4/280 / SunOS 4.0.1 Severity: ??? Problem: Ussualy I have build my application by declaring a number of structures, this could be done using less than 45Mb of heapspace, even if I set the the flags like: System.Control.CG.reducemore := 0; System.Control.CG.rounds := 10; System.Control.CG.bodysize := 20; The system produced from an "exportML" of this takes up app. 3Mb. >From "doc/optimize" I learned that the code could be optimized by enclosing it in one structure. I did like: structure whole : sig < ... > end = struct <The usual stuff ..> end; open whole; It meant that the heapsize had to be increased to 80 Mb and I had to reset the above flags. I observed a bug in the reporting of GC: ... [Major collection... 76% used (18670576/24426980), 34260 msec] [Increasing heap to 59632k] [Major collection... -57% used (25033788/31118476), 44190 msec] [Increasing heap to 68216k] [Major collection... -35% used (30575468/34993364), 54880 msec] ... The "-57%" should be "80%" and the "-35%" should be "87%". But the main problem is that the CG before the "exportML" only decreases the heap to 49Mb, and then it stops with the message "export" - due to no disk space (?) Comments: (appel) Setting these flags for optimization may cause the code generator to generate very large output. Use at your own risk. Status: can't reproduce; the negative percent messages are fixed in 0.64 ------------------------------------------------------------------------------- 186. type error matching against bogus tycon Submitter: Dave Date: 1/12/90 Version: 0.52? Messages: Error: value type in structure doesn't match signature spec name: instantiate spec: Basics.tyvar * Basics.ty -> unit actual: ?.bogus * ?.bogus -> unit Status: can't reproduce -------------------------------------------------------------------------------- 187. parsing clausal definitions with infix functions Submitter: Mick Francis Date: 1/11/90 Version: 0.44(?) Problem: 1) Infix function declarations using parentheses do not parse. E.g. infix xxx; fun (a xxx b) = b; (* Will not compile *) fun (a xxx b) c = c; (* Will not compile *) 2) When an infix identifier appears as the first of more than 2 formal parameters in a function declaration, if the second formal parameter is an identifier, an attempt is made to declare a function with this name. E.g. infix xxx; fun a xxx b c = c; (* Compiles function b ??? *) fun a xxx nil c = c; (* Tries to bind nil - error *) Gamma% njml Standard ML of New Jersey, Version 0.44a, 13 December 1989 val it = () : unit - infix xxx; - fun (a xxx b) y = y; (* Should work *) Error: expected EQUAL, found RPAREN Error: atomic expression expected, found RPAREN Error: declaration or expression expected, found RPAREN - fun (a xxx b) = b; (* Should work *) Error: expected EQUAL, found RPAREN Error: atomic expression expected, found RPAREN Error: declaration or expression expected, found RPAREN - fun a xxx b y = y; (* Shouldn't compile *) val b = fn : 'a -> 'a - fun a xxx nil d = d; Error: improper use of constructor nil in pattern Error: Compiler bug: generalizeTy -- bad arg xxx : 'S * 'T -> undef Incidentally, Poly/ML gets the following wrong :- infix xxx; fun a xxx b d = d; It gives the message :- Error- Constructor (b) has not been declared Found near b(y) It appears to be looking for a pat, not an atpat on either side of the xxx. Status: fixed in 0.52 -------------------------------------------------------------------------------- 188. infinite loop parsing simple functor declaration Submitter: Simon Finn Version: 0.44 Problem: loops trying to compile the following definitions Code: signature TRIVSIG = sig end; functor A(X : TRIVSIG) : TRIVSIG = X; functor B(X : TRIVSIG) : TRIVSIG = A(X); Status: fixed in 0.50 or so ------------------------------------------------------------------------------ 189. confusing error message for bad clausal syntax Submitter: Carl Gunter Date: 1/4/90 Version: 0.44/0.52 Problem: Parser error message is not as helpful as it could be. Transcript - fun (f:('a pair -> int)) x = 2; std_in:3.5-3.24 Error: illegal function symbol in clause Status: fixed -------------------------------------------------------------------------------- 190. unclosed string in interactive system Submitter: Trevor Date: 1/5/90 Version: 0.44 System: SparcStation, SunOs Severity: no prob, bob Problem: error recovery on unclosed string in interactive system Transcript: - wf "/u/trevor/.login = "; (* Shouldn't have done this *) Error: unclosed string (* but this warning came too late *) = ; Error: unclosed string Error: operator is not a function operator: unit in expression: wf "" "" - Comments: Guess I shouldn't have tried to close the string after I hit return. But I should have seen an error message so I would know not to do this. The error message came one line too late. Comment by Appel: The lexer always wants to see the first character of the next token before processing the current token; this could be fixed but it's not worth it. Status: fixed in 0.52 (new parser) -------------------------------------------------------------------------------- 191. Real operators permuted Submitter: Peter Canning <canning@hplabs.hp.com> Date: 2 January 1990 Version: 0.44 System: Sun 3 running SUNOS 4.0 Severity: critical Problem: Several functions in structure Real are incorrect Comments: order of operations in Real structure was wrong Status: fixed in 0.47 -------------------------------------------------------------------------------- 192. bad parsing Submitter: John Reppy Date: 1/6/90 Version: 0.44 Transcript: Standard ML of New Jersey, Version 0.44, 4 December 1989 val it = () : unit - map fn c => (c, ord c); val it = fn : ('a -> 'b) -> 'a list -> 'b list val it = fn : string -> string * int Status: fixed by new parser -------------------------------------------------------------------------------- 193. import types Submitter: Nick Rothwell Date: 1/5/90 Version: 0.44a (0.44 with import fix) Problem: I've enclosed a bug in NJ SML 0.44a, based on a bug report I received from people at HP. I've managed to narrow it down to a simple example. It seems to be a strange interaction between the type import code of the separate compilation mechanism, the functor typechecking, and the checking of record types (of all things!). Unfortunately, I don't know anything about how types are imported under separate compilation, so I can't take it much further. Transcript: I enclose two files, A.sml and B.sml. B.sml is a simple script that imports A. Try the following: use "B.sml" (so that A gets imported and compiled), and then >exit the system<. Start another session and use "B.sml" again. You should get the following error: B.sml, line 8: Error: operator and operand don't agree (tycon mismatch) operator domain: {X:'S} operand: {X:int} in expression: FOO {X=3} Code: *** A.sml *** signature A = sig datatype 'a Foo = FOO of {X: 'a} (* Must be a record type to reproduce the bug. *) end; functor A(): A = (* Must have sig constraint to reproduce the bug *) struct datatype 'a Foo = FOO of {X: 'a} end; *** B.sml *** import "A"; structure ??? = A(); (*Needed to reproduce the bug*) functor F(structure A: A) = struct val _ = A.FOO{X=3} end; Status: fixed in 0.54, fixed better in 0.57 -------------------------------------------------------------------------------- 194. weak type variable syntax Submitter: David Tarditi Date: 12/17/89 Version: 0.44? Problem: There seems to be one slight problem in the documentation on support for imperative type variables as described in the Standard. I took the documentation to mean that '_a is an abbreviation for '1a. This isn't true. If you try the code at the bottom, you'll see this. Code: (* Sample code: The second declaration of y causes a type error *) val x = fn (a,b) => (ref a; ref (a b)); val y = x : ('1a -> '1b) * '1a -> '1b ref; val y = x : ('1a -> '1b) * '_a -> '_b ref Status: fixed in 0.54 -------------------------------------------------------------------------------- 195. Compiler bug: abstractType Submitter: John Reppy Date: 2/12/89 Version: 0.28 Problem: I got a compiler bug message when working on my code generator. Unfortunately I wasn't able to reproduce it in a small example. When I fixed the type error, the bug message went away. I don't know if this is useful to you, but here it is: Transcript: - use "sparc/sparccoder.sml"; [opening sparc/sparccoder.sml] sparc/sparccoder.sml, line 195: Error: operator and operand don't agree (tyco n mismatch) operator domain: register * reg_or_immed * register operand: register * register * register in expression: emit_subcc (a,b,g0) sparc/sparccoder.sml, line 210: Error: Compiler bug: abstractType [closing sparc/sparccoder.sml] Status: probably fixed in 0.54 (can't reproduce) -------------------------------------------------------------------------------- 196. Compiler bug: generalizeTy -- bad arg Submitter: Andrew Appel Date: 12/6/89 Version: 0.44 Problem: The following program yields Compiler bug: generalizeTy -- bad arg in version 0.44. Code: signature COMPLEX = sig type elem val complex: real*real -> elem val + : elem * elem -> elem val - : elem * elem -> elem val * : elem * elem -> elem val / : elem * elem -> elem val ~ : elem -> elem val inv: elem -> elem val abs : elem -> real val conj : elem -> elem val cis: real -> elem end abstraction Complex : COMPLEX = struct open Real type elem = real * real fun complex ri = ri val op + = fn ((a,b),(c,d)) => (a+c,b+d) and op - = fn ((a,b),(c,d)) => (a-c,b-d) and op * = fn ((a,b),(c,d)) => (a*c-b*d, a*d+b*c) and op / = fn ((a,b),(c,d)) => let val z = c*c+d*d in ((a*c+b*d)/z, (b*c-a*d)/z) end and inv = fn (a,b) => let val z = a*a+b*b in (a/z,b/z) end and ~ = fn (a,b) => (~a,~b) and abs = fn (a,b) => a*a+b*b and conj = fn (a,b) => (a,~b) and cis = fn t => (cos t, sin t) end signature FIELD = sig type elem val zero: elem val one: elem val + : elem * elem -> elem val * : elem * elem -> elem val inv: elem -> elem end signature POLYNOMIAL = sig structure F : FIELD type poly val x : poly val const : F.elem -> poly val * : poly * poly -> poly val + : poly * poly -> poly val ~ : poly -> poly val eval: poly -> F.elem -> F.elem val deriv: poly -> poly end functor Polynomial(F : FIELD) : POLYNOMIAL = struct structure F=F type poly = F.elem list val x = [F.zero,F.one] fun const c = [c] fun []+a = a | a+[] = a | (a::b) + (c::d) = F.+(a,c)::(b+d) fun scalarmult(a,[]) = [] | scalarmult(a,b::c) = a*b::scalarmult(a,c) fun []*a = [] | a*[] = [] | a::b*c = scalarmult(a,c) + (F.zero::(b*c)) fun ~ [] = [] | ~ (a::b) = F.~(a) :: ~(b) fun eval p x = let fun f([],z,sum) = sum | f(a::b,z,sum) = f(b,F.*(x,z),sum+F.*(a,z)) in f(p,F.one,F.zero) end fun deriv [] = [] | deriv a::r = let fun f(z,a::b) = F.*(z,a)::f(F.+(z,F.one),b) in f(F.one,r) end end abstraction P = Polynomial(Complex) Status: fixed in 0.52 -------------------------------------------------------------------------------- 197. exportFn size Submitter: Lars Bo Nielsen, Aalborg University, Strandvejen 19, 9000 Aalborg, DENMARK. Email : lbn@iesd.auc.dk Date: Dec. 6 - 1989 Version: 0.43 System: Sun 3/60 -- SunOs 4.0.3 Severity: Depends on the the importness of the the noshare version of the compiler and exportFn Problem: I make standalone versions of the lex and yacc, included in the distribution. I use the following code, to make a standalone version of "smlyacc", and similar for my "smllex" (feeding it to the noshare version of sml): | use "load.sml"; | loadAll(); | open ParseGen; | | fun main (argv, env) = | let | val argc = length argv | val prog = hd argv | in | (if (argc <> 2) then | outputc std_out ("Usage: " ^ prog ^ " file\n") | else | let | val file = hd (tl argv) | in | parseGen file | handle Io s => | outputc std_out | (prog ^ ": Couldn't open file: " | ^ file ^ "\n") | end; | outputc std_out "\n") | end; | | exportFn ("smlyacc", main); The problem then is this: When making "smllex" everything works fine, and I get (on Sun 3/60) a standalone version of 208K. But the "smlyacc" version, though it compiles fine and runs, on more than 2000K. I used the same procedure with version 0.39, and the standalone version of "smlyacc" then was 368K. It seems to me that when exporting "smlyacc", the runtime system isn't thrown away, as when "smllex" was generated. Status: fixed in 0.54 -------------------------------------------------------------------------------- 198. printing exception specs in signatures Submitter: John Reppy Date: 12/2/89 Version: 0.43 Problem: nullary exceptions get printed as "of exn" in signatures Transcript: Standard ML of New Jersey, Version 0.43, 27 November 1989 val it = () : unit - signature S = sig exception Sync end; signature S = sig exception Sync of exn end - exception Sync; exception Sync Status: fixed in 0.52 -------------------------------------------------------------------------------- 199. Compiler bug after unbound signature Submitter: John Reppy Date: 12/1/89 Version: 0.43, 0.52 Problem: Missing signature causes Compiler bug error after unbound signature error. Transcript: - signature SS = sig structure A : AA end; std_in:5.34-5.35 Error: unbound signature: AA Error: Compiler bug: ModUtil.shiftStamps.newEnv - bad arg Status: fixed in 0.56 -------------------------------------------------------------------------------- 200. large integer literals Submitter: Peter Buneman Date: 12/1/89 Version: 0.39 System: Sun 3? Transcript: Standard ML of New Jersey, Version 0.39, 8 September 1989 val it = () : unit - val x = 400000000; val x = 400000000 : int - x + x; val it = 800000000 : int - val y = 800000000; val y = ~273741824 : int (* problem *) - x+x; val it = 800000000 : int - x*x; uncaught exception Overflow Status: fixed in 0.52 (on Sun 3 at least) -------------------------------------------------------------------------------- 201. funny tycon aliasing behavior Submitter: John Reppy Date: 8/18/89 Version: 0.33 Transcript Standard ML of New Jersey, Version 0.33, 1 April 1989 val it = () : unit - structure A = struct datatype foo = Bar of int end = ; structure A : sig datatype foo con Bar : int -> foo end - structure B : sig datatype foo' = Bar of int end = struct = open A = type foo' = foo = end; structure B : sig datatype foo' con Bar : int -> A.foo end Status: fixed in 0.56 -------------------------------------------------------------------------------- 202. type error not caught? Submitter: Norman Ramsey Date: 8/28/89 Version: ? Problem: I believe that the following file should generate a type error, but it doesn't. In particular, the line val _ = begin_str "replicas" ufanout(c,chans) should force chans to be type 'a chan list when c is type 'a chan. Code: datatype 'a chan = CHAN of 'a signature BADGUYS = sig val mkchan : unit -> '1a chan val ufanout : '2a chan * '2a chan list -> 'b val begin_str : string -> ('a -> 'b) -> 'a -> unit end signature WONKY = sig val ureplicas : int -> '2a chan -> '6b chan list (* wrong! should be int -> '2a chan -> '2a chan list *) end functor buggy(bad:BADGUYS):WONKY = struct open bad fun ureplicas n c = (* n unsynchronized copies of channel c *) let fun channels(l,0) = l | channels(l,n) = channels(mkchan()::l,n-1) val chans = channels(nil,n) val _ = begin_str "replicas" ufanout(c,chans) in chans end end Transcript: (0.52) - use "code/bug.202"; [opening code/bug.202] code/bug.202:16.36-28.3 Error: value type in structure doesn't match signature spec name: ureplicas spec: int -> '2a chan -> '6b chan list actual: int -> '1a chan -> '6b chan list Status: fixed in 0.56 -------------------------------------------------------------------------------- 203. printing of infix specs in signatures Submitter: Trevor Jim Date: 4/3/89 Version: 0.32, 0.52 Problem: infix specs are printed with two precedence numbers Transcript: - signature SS = sig infix 5 bar end; signature SS = sig infix 10 10 bar end Status: fixed in 0.54 -------------------------------------------------------------------------------- 204. constructors printed when not accessible Submitter: Dave Berry Date: 2/2/89 Version: 0.52 Problem: constructors of a datatype in a structure are printed in the structure signature even though they are masked out by a signature constraint. Transcript: - signature S1 = sig type d end; signature S1 = sig type d end - structure A : S1 = struct datatype d = A | B of int end; structure A : sig datatype d con A : d con B : int -> d end Status: fixed in 0.56 -------------------------------------------------------------------------------- 205. performance problem with many opens in a structure Submitter: Jawahar Malhotra Problem: Code: structure A = struct (* 30 val declarations *) end structure B,C,D... similar structure S = struct open A B C D E F G end Status: fixed in 0.58 ------------------------------------------------------------------------------ 206. unhelpful parser error message (new parser) Submitter: Dave Date: 3/15/90 Version: 0.52 Transcript: - structure A = struct val x = if true then if true then 1 else 2 end; std_in:4.1 Error: syntax error found at END - Comment: what we need is %prefer ELSE 0, that is, the ability to give a hint for the insertion of two tokens in a row. Right now, %prefer can only hint about single-token insertions. This fix has to be done in mlyacc. Status: open ------------------------------------------------------------------------------- 207. uncaught tycStamp exception Submitter: Nevin.Heintze@PROOF.ERGO.CS.CMU.EDU Date: 4/3/90 Version: 0.44 (0.53) Problem: tycStamp raised during compilation Code: (file bug207.sml) signature SS = sig datatype t = B of t | A of t list end functor F(X:SS) = struct fun f(X.B(v)) = (v :: nil = v :: nil) | f _ = false end Transcript: Standard ML of New Jersey, Version 0.44, 4 December 1989 val it = () : unit - use "bug.sml"; [opening bug.sml] bug.sml, line 11: Error: Compiler bug: tycStamp equal: type = ?.ttt list [closing bug.sml] - Comments: The problem appears to be the typing of the equality test. It is sensitive to the use of lists, both in the datatype definition and the equality test. Status: fixed in 0.56 ------------------------------------------------------------------------------- 208. bug in optimizer causing bad free variable Submitter: Appel & MacQueen Date: 4/27/90 Version: 0.56 Problem: impossible error in cpsopt phase, on MIPS machine, with default optimization settings Code: functor MipsCoder(val emit : 'a -> unit) = struct fun needs _ = true fun pass now = let fun gen inst = if now andalso needs() then () else if now then let fun gen1() = gen(raise Match) in case inst of NONE => gen1() | SOME b => let fun bc1f offset = () fun bc1t offset = () in if inst=NONE then (emit((if b then bc1t else bc1f) inst); gen1()) else () end end else () in gen end val assemble = pass true end Comment: this can be avoided by setting closurestrategy to 2, which we now do; Trevor may fix this bug eventually. Status: avoided in 0.60 ------------------------------------------------------------------------------- 209. equality types and functors, again Submitter: Appel & MacQueen Date: 4/30/90 Version: 0.56 Problem: Problem in eqtypes/defineEqTycon/eqty. failure when attempting to reevaluate equality properties of generative/defined tycons in functor body after functor is applied. Code: signature S1 = sig type t end; structure A = struct type t = int end; functor F(X : S1) = struct structure B = struct datatype s1 = K of X.t end type s = B.s1 end; structure C = F(A); Comments: we've put in a warning message, and assumed a non-equality type when this happens. (still causes impossible error in 0.56). Status: "fixed" by following the lead of the Definition and not recalculating equality properties on functor applications. -------------------------------------------------------------------------------- 210. sharing checking with fixed stamps Submitter: Appel & MacQueen Date: 5/3/90 Version: 0.56 Problem: Union exception is not caught when sharing specs try to identify two distinct types or structures (with differing fixed stamps). Code: structure S = struct end; structure T = struct end; signature Q = sig sharing S=T end; Comments: Easy to fix. Just add a handler for the Union exception in Sharing.doSharing and produce and appropriate error message. Status: fixed in 0.57 -------------------------------------------------------------------------------- 211. Union exception processing correct sharing in functor body Submitter: MacQueen Date: 5/4/90 Version: 0.56 Problem: Union exception is raised in doSharing when processing correct sharing specs in a functor body. Code: (* bug211.sml *) functor F(type t) = struct structure K = struct type s = t end structure M : sig structure L : sig type s sharing type s = t end sharing L=K end = struct structure L = K end end; Comments: The bug occurs because the type definition shortcut (for "type s = t", s is made a copy (modulo path) of t) is not done when t has a bound stamp, as in the code above. Here s is a DEFtyc tycon with a different stamp from t. Status: fixed in 0.58 -------------------------------------------------------------------------------- 212. polymorphic exception declarations Submitter: Dave Berry (for Jo Blishen) (submitted to ml-bugs) Date: 5/11/90 Version: 0.56 Severity: major Problem: rejects proper weak polymorphic type for locally declared exception Code: fun f (l:'_a) = let exception E of '_a in (raise (E l)) handle E t => t end; Comments: Worked in 0.44a. Status: fixed in 0.58 (suspect related bugs because of the way TyvarSet.union_tyvars is defined.) -------------------------------------------------------------------------------- 213. equality on int*int Submitter: Soren Christensen, University of Aarhus, Computer Science Dep., Denmark schristensen@daimi.dk Date: 16 may 90 Version: 0.56 System: Sun4/280 / SunOS 4.0.1 Severity: Critical Problem: failure compiling equality on type int*int Code: (* filename: bug213.sml *) (3,3,) = (3,3); Transcript: Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - use "fun"; [opening fun] datatype 'a $$$ con $ : 'a -> 'a $$$ con $$ : 'a $$$ LOOKUP FAILS in close(FIX 2795 2799 2707 2996 ) on 2927 in environment: 2792 2790 2791 [closing fun] uncaught exception Match - val x = 5; Illegal instruction Comments: [Christensen] It looks like the compiler is messed up after this error. It core-dumps parsing the next declaration. Version 0.44 has no problem handling this declaration. [dbm] The code "(3,3) = (3,3);" reproduces the bug. Haven't been able to reproduce the core dump. Status: fixed in 0.58. (bug was in codegen) -------------------------------------------------------------------------------- 214. Compiler bug: EnvAccess.lookPath when printing Submitter: Frank Pfenning (Frank.Pfenning@proof.ergo.cs.cmu.edu Date: 5/17/90 Version: 0.56 Severity: critical Problem: Compiler bug: EnvAccess.lookPath occurs when printing a top-level result. Code: signature TERM = sig datatype term = Const of string and varbind = Varbind of string * term end functor Term ( ) : TERM = struct datatype term = Const of string and varbind = Varbind of string * term end signature BUG = sig structure Term : TERM type progentry val bug : progentry list end functor Bug ( structure Term : TERM ) : BUG = struct structure Term = Term open Term datatype progentry = Progentry of string * Term.term * Term.varbind list * Term.term val bug = [Progentry("test",Const "test", [Varbind("v",Const("test"))],Const("test"))] end structure Term : TERM = Term (); structure Bug : BUG = Bug ( structure Term = Term ); Bug.bug; Status: fixed in 0.58 -------------------------------------------------------------------------------- 215. sin gives incorrect values Submitter: Thomas M. Breuel (tmb@ai.mit.edu) Date: 5/18/90 Version: 0.59 System: SPARC/SunOS 4.0.3c Severity: major Problem: sin function is incorrect Transcript: (* SparcStation 1, SunOS 4.0 *) Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - sin(4.0); val it = ~0.756802495307928 : real - sin(5.0); val it = ~0.958924274663138 : real - sin(6.0); val it = 0.279415498198926 : real - (* ^^^^^^^^^^^^^^^^^ this should be negative, since it is between pi and 2 pi *) Comments: Probably someone transcribed the sin function from the Berkeley math library incorrectly in boot/math.sml. Status: fixed in 0.58 (Appel) -------------------------------------------------------------------------------- 216. floating point on SPARC Submitter: tmb@ai.mit.edu Date: Sat May 19 04:52:35 EDT 1990 Version: 0.56 System: Sun SS1, Sun OS 4.0.3 Severity: critical Problem: floating point broken in Sparc compiler?! Transcript: (everything that begins with a TAB comes from an actual transcript) Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - fun ilist(from:int,to:int,step:int) = f = if (from<to) then (f from)::ilist(from+step,to,step) f else []; val ilist = fn : int * int * int -> (int -> 'a) -> 'a list - ilist(0,10,1) (fn x => x); val it = [0,1,2,3,4,5,6,7,8,9] : int list - ilist(0,10,1) print; 0123456789val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list all is as it should be--so far - fun rlist(from:real,to:real,step:real) f = = if (from<to) then (f from)::rlist(from+step,to,step) f else []; val rlist = fn : real * real * real -> (real -> 'a) -> 'a list this is the same definition with different type constraints - rlist(0.0,10.0,1.0) (fn x => x); val it = [] : real list ??? - rlist(0.0,10.0,1.0) (fn x => x); val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list same expression, different result??? - rlist(0.0,10.0,1.0) (fn x => x); val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list now it seems to work... - rlist(0.0,10.0,1.0) print; 0.0val it = [()] : (unit) list but it still doesn't work with "print" - rlist(0.0,10.0,1.0) (fn x => x); val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list - Comments: These problems don't occur on the m68 version of SML. In fact, the problem with "sin" that I reported previously also doesn't occur with the m68 version. Maybe this is an installation problem, but if it is, then there is probably something wrong with the makeml script. The Sparc version was generated with "makeml -sun4 -sunos" if I remember correctly. Here is the transcript from a Sun-3: Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - [opening /tmp_mnt/home/vi/tmb/cad/bad.sml] val identity = fn : 'a -> 'a val ilist = fn : int * int * int -> (int -> 'a) -> 'a list val rlist = fn : real * real * real -> (real -> 'a) -> 'a list [closing /tmp_mnt/home/vi/tmb/cad/bad.sml] val it = () : unit these are the same definitions as above - ilist(0,10,1) (fn x => x); val it = [0,1,2,3,4,5,6,7,8,9] : int list - ilist(0,10,1) print; 0123456789val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list - rlist(0.0,10.0,1.0) (fn x => x); val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0] : real list - rlist(0.0,10.0,1.0) print; 0.01.02.03.04.05.06.07.08.09.0val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list - sin 6.0; val it = ~0.279415498198926 : real - sin 5.0; val it = ~0.958924274663138 : real - Status: fixed in 0.58 (Reppy) -------------------------------------------------------------------------------- 217. simultaneous opens Submitter: Larry Paulson (lcp@lfcs.ed.ac.uk) Date: 5/25/90 Version: 0.56 Severity: major Problem: opening several structures simultaneously can result in Runbind Code: code/bug217.sml structure A = struct val x = 3 end; structure B = struct structure A = A; end; open A B; x; Comments: This works if "open A B;" is replaced with "open A; open B;" Status: fixed in 0.59 -------------------------------------------------------------------------------- 218. compiler bug after unbound variable Submitter: John Reppy (jhr@cs.cornell.edu) Date: 5/26/90 Version: 0.57 Severity: major Problem: Compiler bug: generalizeTy -- bad arg occurs after top level unbound var Transcript: - x; std_in:2.1 Error: unbound variable x Error: Compiler bug: generalizeTy -- bad arg Status: fixed in 0.59 -------------------------------------------------------------------------------- 219. parsing layered patterns Submitter: Andrew Appel Date: 5/90 Version: 0.56 and later Severity: minor Problem: parsing of layered pattern is too liberal. An atomic pattern is accepted where a variable is required by the Definition syntax. Code: let val (x) as (y :: z) = [1,2] in x end Comments: Seems to require nontrivial change to the mlyacc grammar Status: open -------------------------------------------------------------------------------- 220. Match exception after error Submitter: John Reppy Date: 6/1/90 Version: 0.58 System: Sun 4 Severity: minor Problem: uncaught exception Match after signature matching error Code: signature S = sig type foo val f : int -> foo end structure Foo : S = struct datatype foo_t = Foo of int val f = Foo end Transcript: xxx.sml:6.21-9.3 Error: unmatched type spec: foo xxx.sml:6.21-9.3 Error: value type in structure doesn't match signature spec name: f spec: int -> [closing xxx.sml] uncaught exception Match - Comment: Now produces std_in:10.21-13.3 Error: unmatched type spec: foo std_in:10.21-13.3 Error: value type in structure doesn't match signature spec name: f spec: int -> NULLtyc actual: int -> foo_t The NULLtyc is undesirable. Status: partially fixed (before 0.65) -------------------------------------------------------------------------------- 221. profiling broken Submitter: Benjamin Pierce (Benjamin.Pierce%proof.ergo.cs.cmu.edu Date: 5/22/1990 System: 0.56 (and later) Problem: Profiling provides call counts bug not timings. For separately compiled modules, profiling provides neither call counts nor timings. Transcript: (1) for separately compiled code %time cumsecs #call ms/call name .00 0 (toplevel) .00 0 (gc) .00 0 (unprofiled) (2) for "used" code %time cumsecs #call ms/call name .00 2398 .0000 anon.AType.==.anon .00 2398 .0000 anon.AType.== .00 2051 .0000 anon.Id.==.anon .00 2051 .0000 anon.Id.== .00 1890 .0000 anon.AType.apply_rule.anon [etc...] Fix: Some of the problems may be caused by handleprof() in runtime/signal.c being braindamaged. I changed it to be: SIGH_RET_TYPE handleprof () { extern ML_val_t current0[]; ML_val_t cur_barray = current0[1]; cur_barray[1] = (unsigned int)INT_incr(cur_barray[1],1); } and it seemed to work for simple examples. However, I'm not too sure that the times mean anything for larger examples. Perhaps there's some bad interaction with GC? Status: fixed in 0.70 -------------------------------------------------------------------------------- 222. equality on ref types Submitter: Larry Paulson <lcp@lfcs.edinburgh.ac.uk> Date: 11/6/90 Version: 0.56, 0.59 Severity: major Problem: ref type not being recognized as unconditionally an equality type Transcript: - fun silly x = (ref x = ref x); val silly = fn : ''1a -> bool - silly not; std_in:4.1-4.9 Error: operator and operand don't agree (equality type required) operator domain: ''0S operand: bool -> bool in expression: silly not And anyway the type checker behaves inconsistently by admitting the following: - ref not = ref not; val it = false : bool Status: fixed (before 0.65) -------------------------------------------------------------------------------- 223. nontty standard input and uncaught exceptions Submitter: KINOSHITA Yoshiki yoshiki@etl.go.jp Date: 4, June 1990 Version: SML of NJ 0.56 System: Sparc Station 330 (SUN4), SUN-OS 4.0.3 (generic version) Severity: major Problem: If the standard input is a pipe, the system ends abnormally after it sends an error message. Code: None. The problem concerns with the interface to UNIX. Transcript: % cat - | sml Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - foo; std_in:2.1-2.3 Error: unbound variable foo uncaught exception Stop ^Z Stopped % jobs [1] + Stopped cat - | Done sml % Comments: This problem makes it impossible to use the system with its input sent through a UNIX filter. from jhr: You might call this a feature. It appears that the person who wrote the top-level loop code (interact.sml), decided that exceptions should only be caught at the top-level loop when std_in is a tty (look at lines 292-309 in interact.sml). The following work-around avoids the problem <jhr@rocky:76> cat - | sml Standard ML of New Jersey, Version 0.59, 4 June 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - set_term_in(std_in, true); val it = () : unit - foo; std_in:3.1-3.3 Error: unbound variable foo - 1+2; val it = 3 : int - But, maybe the code should change. It isn't clear to me what the correct semantics are in this case. This problem came up here at Cornell when Bill Aitken was using "rsh" to run sml on a remote machine. Status: fixed in 0.65 -------------------------------------------------------------------------------- 224. weakness 0 type variables in let declaration Submitter: Larry Paulson Date: 6/4/90 Version: 0.56, 0.59 Severity: major Problem: A weakness 0 type variable should be admitted, but not generalized, in local declarations. Transcript: <transcript of session illustrating problem> - let val f = ref(fn x => x) in f := not; !f true end; std_in:1.9-1.26 Error: nongeneric weak type variable f : ('0Y -> '0Y) ref std_in:1.9-1.26 Error: nongeneric weak type variable f : ('0Y -> '0Y) ref Comments: This worked in 0.44. Status: fixed (before 0.65) -------------------------------------------------------------------------------- 225. import broken in 0.59 Submitter: Lars Bo Nielsen <lbn@iesd.auc.dk> Date: Jun 5, 1990 Version: Version 0.59 System: Sparc/sunos Severity: critical Problem: import broken. A simple 'import "file"' doesn't work, if only 'file.sml' is present. If 'file.bin' is present it works. I DIDN'T have this problem with version 0.56. Transcript: The following example shows the problem. SHELL% ll total 68 2 calc.dsl 11 calc.grm.sml 31 calc.parser.sml 3 calc.grm 1 calc.instr 2 calc.sml 4 calc.grm.desc 2 calc.lex 1 calc.grm.sig 11 calc.lex.sml SHELL% sml Standard ML of New Jersey, Version 0.59, 4 June 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - import "calc.parser"; uncaught exception SystemCall - ^Z Stopped SHELL% touch calc.parser.bin SHELL% fg sml - import "calc.parser"; [reading calc.parser.bin... ] [calc.parser.bin is the wrong format; recompiling [closing calc.parser.bin] [reading calc.parser.sml] [Major collection... 69% used (1475096/2123360), 1700 msec] [Increasing heap to 4451k] ..... etc ..... Status: fixed in 0.60 (jhr) -------------------------------------------------------------------------------- 226. uncaught exception Match while printing type (same as 220) Submitter: John Reppy Date: 6/1/90 Version: 0.56 Severity: major Problem: Uncaught Match exception occurs when printing out the spec type in an error message. Code: signature S = sig type foo val f : int -> foo end structure Foo : S = struct datatype foo_t = Foo of int val f = Foo end Transcript: xxx.sml:6.21-9.3 Error: unmatched type spec: foo xxx.sml:6.21-9.3 Error: value type in structure doesn't match signature spec name: f spec: int -> [closing xxx.sml] uncaught exception Match - Status: partially fixed (before 0.65) -------------------------------------------------------------------------------- 227. equality property of datatypes Submitter: Brian Boutel (brian@comp.vuw.ac.nz) Date: May 25 1990 Version: 0.56 System: Sun3/sunos and H-P workstation (More/bsd) Severity: major Problem: Equality test for recursive types may fail in various ways (similar to bug 45, reported fixed) Description: Given datatype 'a d1 = c11 | c12 of ('a * 'a d1); datatype 'a d2 = c21 | c22 of ('a d2 * 'a ); datatype d3 = c31 | c32 of ( d3 * int); a) c11 = c11 works correctly b) c12(1,c11) = c12(1,c11) gets uncaught exception Match (* ok in 0.59 *) c) c21 = c21 loops forever (* in 0.59 as well *) d) c22(c21,1) = c22(c21,1) gets uncaught exception Match (* ok in 0.59 *) e) c31 = c31 works correctly f) c32(c31,1) = c32(c31,1) gets uncaught exception Match (* ok in 0.59 *) Transcript: (with System.Control.debugging := true) b) - c12(1,c11) = c12(1,c11); parse semantics BEFORE: val it = = (c12 (1,c11),c12 (1,c11)) AFTER: val it = = (c12 (1,c11),c12 (1,c11)) test: int d1 test: int d1 find: int d1 find-notfound enter: int d1 test: int * int d1 find: int * int d1 find-notfound enter: int * int d1 test: int test: int test: int d1 find: int d1 translate reorder convert cpsopt closure LOOKUP FAILS in close(FIX 4146 4150 ) on 4161 in environment: 4143 4141 4142 globalfix spill codegen uncaught exception Match - c) - c21 = c21; parse semantics BEFORE: val it = = (c21,c21) AFTER: val it = = (c21,c21) test: ''S d2 test: ''S d2 find: ''S d2 find-notfound enter: ''S d2 test: ''S d2 * ''S find: ''S d2 * ''S find-notfound enter: ''S d2 * ''S test: ''S d2 find: ''S d2 find-notfound enter: ''S d2 test: ''S d2 * ''S find: ''S d2 * ''S find-notfound enter: ''S d2 * ''S test: ''S d2 find: ''S d2 find-notfound ..... Status: fixed in 0.60 -------------------------------------------------------------------------------- 228. string to real conversion Submitter: jubu@tub.UUCP or jubu@tub.BITNET (Juergen Buntrock TUB) Date: Fri Apr 27 14:12:10 MET DST 1990 Version: 0.44 System: Sun4, SunOS Release 4.0.3c Severity: critical Code: and Transcript: Script started on Fri Apr 27 13:49:54 1990 jubu@curry mlj/handel 1) cat bug.sml exception bad_number; fun string2real (s : string) = let val (fac,li) = case explode s of "-" :: li => (~1.0,li) | "+" :: li => (1.0,li) | li => (1.0,li) val (res,_) = (revfold (fn (c,(a,fac1)) => let val n = ord c - ord "0" in output std_out ""; (* comiler bug ! *) if fac1 > 0.0 then if n < 0 orelse n > 9 then raise bad_number else (a + fac1 * (real n),fac1/10.0) else if c = "." then (a,1.0/10.0) else if n < 0 orelse n > 9 then raise bad_number else (10.0 * a + (real n),0.0) end) li (0.0,0.0)) in res * fac end fun string2real_bug (s : string) = let val (fac,li) = case explode s of "-" :: li => (~1.0,li) | "+" :: li => (1.0,li) | li => (1.0,li) val (res,_) = (revfold (fn (c,(a,fac1)) => let val n = ord c - ord "0" in if fac1 > 0.0 then if n < 0 orelse n > 9 then raise bad_number else (a + fac1 * (real n),fac1/10.0) else if c = "." then (a,1.0/10.0) else if n < 0 orelse n > 9 then raise bad_number else (10.0 * a + (real n),0.0) end) li (0.0,0.0)) in res * fac end jubu@curry mlj/handel 2) sml Standard ML of New Jersey, Version 0.44, 4 December 1989 val it = () : unit - use"bug.sml"; [opening bug.sml] exception bad_number val string2real = fn : string -> real val string2real_bug = fn : string -> real [closing bug.sml] val it = () : unit - string2real "123.456"; val it = 123.456 : real - string2real_bug "123.456"; val it = 12346.0 : real - open System.Control.CG; structure M68 : sig val trapv : bool ref end val reducemore = ref 15 : int ref val printit = ref false : bool ref val knowngen = ref 12 : int ref val etasplit = ref true : bool ref val comment = ref false : bool ref val knowncl = ref 0 : int ref val scheduling = ref true : bool ref val printsize = ref false : bool ref val reduce = ref true : bool ref val closureprint = ref false : bool ref val stdgen = ref 64 : int ref val alphac = ref true : bool ref val profile = ref false : bool ref val hoist = ref true : bool ref val foldconst = ref true : bool ref val tailrecur = ref true : bool ref val path = ref false : bool ref val rounds = ref 1 : int ref val closureStrategy = ref 1 : int ref val recordopt = ref true : bool ref val bodysize = ref 0 : int ref val tail = ref true : bool ref - script done on Fri Apr 27 13:55:57 1990 Comments: the Sun3 Compiler is correct Status: fixed in 0.56 -------------------------------------------------------------------------------- 229. uncaught Match after signature spec error Submitter: Peter Buneman Date: 4/21/89 Version: 0.59 Severity: major Problem: Following code produces uncaught Match exception Code: signature SS = sig type t1 val t2:t1 end; structure ss:SS = struct local datatype t = T of int in val t2 = T 3 end end; Comment: Output in 0.65 is std_in:8.1-12.3 Error: unmatched type spec: t1 std_in:8.1-12.3 Error: value type in structure doesn't match signature spec name: t2 spec: NULLtyc actual: ?.ss.t NULLtyc for spec is undesirable (similar to 220,226 problem). Status: partially fixed (before 0.65) -------------------------------------------------------------------------------- 230. printing reals on mips Submitter: David MacQueen, Andrew Tolmach Date: 6/12/90 Version: 0.59 System: MIPS, RISCos Severity: critical Problem: Uncaught exception Overflow when printing real numbers at top level. Infinite loop in other cases (e.g. code/bug230.sml). Transcript: - 1.0; val it = uncaught exception Overflow - Comment: works ok on Sun3 and Sun4. works ok on DECsystem (with MIPS chip) / Ultrix Status: fixed in 0.64 -------------------------------------------------------------------------------- 231. equality property of DEFtyc Submitter: Nick Rothwell Date: 6/21/90 Version: 0.56? Severity: major Problem: A type abbreviation for an abstract type admits equality. Code: abstype A = A with type B = A end; fn (x: B) => (x=x); Comments: The type name associated with A (and therefore with B) should be stripped of its equality attribute outside the "abstype". Status: fixed in 0.69 -------------------------------------------------------------------------------- 232. user bound type variable in exception declaration Submitter: Jo Blishen, Nick Rothwell Date: 6/20/90 Version: 0.59 Severity: minor Problem: User-bound tyvar is not generalized at val binding containing it. Transcript: - fun f l = let exception E of '_a in (raise (E l)) handle E t => t end; std_in:2.30-2.32 Error: unbound tyvars in exception declaration Comments: According to the Definition '_a should be considered bound at the outermost val (fun f l ...) where it is the type of the lambda-bound variable l. Status: fixed in 0.65 -------------------------------------------------------------------------------- 233. opening locally declared structure causes Runbind Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: Wed Jun 20 17:21:17 BST 1990 Version: 0.56 (applies to 0.59 as well I believe) System: Sun3, SunOS 4.1 Severity: You decide.... Problem: You cannot declare a local structure and open it. Transcript: Standard ML of New Jersey, Version 0.56, 13 April 1990 val it = () : unit - local = structure Bug = = struct = val message = "Try to evaluate me !" = end = in = open Bug = end ; open Bug - message; uncaught exception Runbind - Status: fixed in 0.60 -------------------------------------------------------------------------------- 234. Compiler Bug: abstractBody.abstractType 1 Submitter: deutsch@poly.polytechnique.fr. Alain Deutsch, Laboratoire d'Informatique de l'Ecole Polytechnique (LIX) 91128 Palaiseau Cedex France. Date: Tue Jun 19 11:04:05 MET DST 1990 Version: Standard ML of New Jersey, Version 0.56, 13 April 1990 System: Sun 3/60, SunOS Release 4.0_Export Severity: major (?) Problem: Compiler Bug: abstractBody.abstractType 1 Code: Too long, ommited. Transcript: - use "/home/icsla/deutsch/ESTFM/basic_ev.sml"; [opening /home/icsla/deutsch/ESTFM/basic_ev.sml] [reading Powerset.bin... done] signature FunctionLattice signature ProductLattice signature OrderedSet signature Lattice signature Product signature PartialFunction signature TotalFunction functor Powerset [reading HashTable.bin... done] signature arrayext functor HashTable functor arrayext [reading lattice.sig.bin... done] signature FunctionLattice signature ProductLattice signature OrderedSet signature Lattice signature Product signature PartialFunction signature TotalFunction [reading Syntax.sig.bin... done] signature Syntax [reading StrgHash.sig.bin... done] signature StrgHash [reading Error.sig.bin... done] signature Error [reading ListUtilities.sig.bin... [Major collection... 66% used (2325300/3480644), 2680 msec] [Increasing heap to 7023k] done] signature ListUtilities [reading Io.sig.bin... done] signature Io [closing /home/icsla/deutsch/ESTFM/basic_ev.sml] /home/icsla/deutsch/ESTFM/basic_ev.sml:20.3 Compiler Bug: abstractBody.abstractType 1 - Comments: the bug is not systematic, and hard to reproduce, this is why the source code has been ommited, as I have not been able to isolate the faulty part of the source. Status: fixed in 0.65 (same as 261) -------------------------------------------------------------------------------- 235. repeated type variables in typdesc and datdesc Submitter: Don Sannella <dts@informatik.uni-Bremen.de> Date: 6/13/90 Version: 0.44? Severity: major Problem: The Definition of SML seems to allow repeated type variables in a typdesc and datdesc, making the following signatures legal: signature SIG1 = sig eqtype ('a,'a) t1 type ('a,'a) t2 end signature SIG2 = sig datatype ('a,'a) t3 = foo of 'a end Section 2.9 forbids repeated variables in a typbind and datbind, but I don't see anything forbidding it in a typdesc or datdesc. I assume below that the omission of a syntactic restriction here was intentional. Repeated type variables in a typdesc seem unproblematic if strange, since the semantics only looks at the number of variables. SML-NJ accepts SIG1 above, and treats it the same as a signature without repeated type variables, which is correct. Repeated type variables in a datdesc are more of a problem, since the constructors refer to them. According to the Definition, foo in SIG2 above gets type 'a -> ('a,'a) t3. Both of the following structures then match SIG2: structure A = struct datatype ('a,'b) t3 = foo of 'a end structure B = struct datatype ('a,'b) t3 = foo of 'b end SML-NJ (version 0.44a) says foo : 'a -> ('a,'b) t3, which is wrong. The result of this is that A matches SIG2 but B does not. I don't know about Poly-SML, since I don't have it here. Status: fixed in 0.65 -------------------------------------------------------------------------------- 236. Mach problems in 0.59 Submitter: David Tarditi Date: 6/18/90 Version: 0.59 System: Mach Severity: critical Comments: I have installed version 0.59 on Vaxes, Suns, and Pmaxes running Mach. There were two problems: VAX.prim.s contained a reference to the variable maskSignals. The name should be _maskSignals instead. The file export.c should also include the file ml_os.h, which contains some definitions needed for Decstations running Mach. Status: fixed in 0.60 -------------------------------------------------------------------------------- 237. Can't parse most-negative integer constant Submitter: David Berry Date: 6/5/90 Version: 0.56 System: All Severity: mild Comments: - ~1073741823; exception Overflow - ~1073741822; val it = ~1073741822: int - it - 1; val it = ~1073741823: int Status: fixed in 0.60 -------------------------------------------------------------------------------- 238. div is unreliable at extremes Submitter: Andrew Appel Date: 7/5/90 Version: 0.56 System: All Severity: mild Comments: - val a = ~1073741822 - 2; val a = ~1073741824: int - a div 2; uncaught exception Overflow; Status: fixed in 0.60 -------------------------------------------------------------------------------- 239. INCONSISTENT exception raised in sharing analysis Submitter: Nick Date: 13 July Version: 0.56, 0.59 System: <irrelevant> Severity: Serious Problem: Internal exception raised in the typechecker during sharing analysis Code: signature A = sig type A datatype Foo = FOO of A end; signature B = sig type B end; signature C = sig datatype C = C of int -> int end; functor XYZZY(structure A: A structure B: B sharing type A.A = B.B structure C: C sharing type C.C = B.B ) = struct end; Transcript: signature A = sig type A datatype Foo con FOO : A -> Foo end signature B = sig type B end signature C = sig datatype C con C : (int -> int) -> C end [closing Kit/foo.sml] uncaught exception INCONSISTENT Status: fixed in 0.61 (dbm) -------------------------------------------------------------------------------- 240. concrete printing of abstype value Submitter: Allen Leung. allen@sbcs.sunysb.edu Date: July 12th, 1990 Version: v59 4 June, 1990 System: SUN 3 on bsd Severity: minor Problem: Toplevel printing of abstype is transparent. Code: - abstype Foo = Foo of int = with fun foo i = Foo i end = val bar = foo 0; > type Foo > val foo = fn : int -> Foo > val bar = Foo 0 : Foo (* instead of - : Foo *) - Transcript: Comments: Is this a new feature of v59+? It does help debugging. Status: fixed in 0.64 -------------------------------------------------------------------------------- 241. sharing constraint error ignored Submitter: David Turner Date: 12 July '90 Version: 0.59 System: Sun4 Severity: Slightly irritating Problem: Ignores error in sharing constraint even though it obviously detects it. Input: - signature S = sig type t end; - functor F (structure A : S structure B : S sharing type B.t = A.s) = struct end; Output: Error: unbound type in structure: s functor F : <sig> Comment: Nonstandard function used in doSharing to report the bug. In 0.65 error message is: std_in:9.6-11.23 Error: unbound type in structure: s This doesn't provide as much useful information as it should. Error message should read something like "unbound type A.s in sharing spec". Status: fixed in 0.65 ------------------------------------------------------------------------------- 242. incorrect forward referencing allowed Submitter: Nick Date: 12 July '90 Version: 0.56, 0.59 System: Irrelevant Severity: Major (& Embarrassing?) Problem: Incorrect forward referencing when analysing SPECs in functor arguments. Input: signature SIG = sig type t end functor F(structure STR1: sig type t end sharing type STR1.t = Foo.t structure Foo: SIG ) = struct end; Output: functor F: <sig> Status: fixed in 0.73 -------------------------------------------------------------------------------- 243. include compiler bug Submitter: Nick Rothwell <nick@lfcs.edinburgh.ac.uk> Date: Thu, 5 Jul 90 17:09:30 BST Version: 0.59 Problem: The following file produces the error Compiler bug: Parse.includeSig.newTyc. Code: (* This "batch" file has been generated from the original sources by MAKE. If you want to make alterations, make them to the originals, and execute Make.make_task again. *) (*$DECTREE_DT*) (* Just the bare datatype for decision trees. *) signature DECTREE_DT = sig type lab type lvar type longvar type longcon type longexcon type scon type pat type type_info eqtype (*pah!*) RuleNum sharing type RuleNum = int type Decision type (''a, 'b) map datatype 'a option = NONE | SOME of 'a datatype DecisionTree = LAB_DECOMPOSE of {bind: lvar, parent: lvar, lab: lab, child: DecisionTree, info: type_info } | CON_DECOMPOSE of {bind: lvar, parent: lvar, child: DecisionTree} | EXCON_DECOMPOSE of {bind: lvar, parent: lvar, child: DecisionTree} | CON_SWITCH of {arg: lvar, selections: (longcon, DecisionTree) map, wildcard: DecisionTree option, (* An `option' because we may notice that all the constructors are present. *) info: type_info } | SCON_SWITCH of {arg: lvar, selections: (scon, DecisionTree) map, wildcard: DecisionTree } | EXCON_SWITCH of {arg: lvar, selections: (longexcon * DecisionTree) list, wildcard: DecisionTree } | END of {ruleNum: RuleNum, environment: (longvar, lvar) map } | FAIL end; (*$MATCH_COMPILER: DECTREE_DT*) (* The match compiler interface; the actual match compiler is built from a number of sub-functors, but this top-level interface is the only one which the rest of the compiler cares about. Given a series of patterns, it returns a DecisionTree (which is essentially an abstract form of the final lambda-code), in which all the lvars for identifiers and temporaries have been generated. At each leaf of the decision tree, there's a single rule number (the rule reached by this series of decisions), and an environment from identifiers to lvars, which is used to compile the right-hand-side expression for this rule. Nice, huh? *) signature MATCH_COMPILER = sig include DECTREE_DT val matchCompiler: lvar * pat list * {warnInexhaustive: bool, warnNoBindings: bool} -> DecisionTree (* these flags are set when the warnings are required. *) type StringTree val layoutDecisionTree: DecisionTree -> StringTree end; Status: fixed in 0.69 ------------------------------------------------------------------------------- 244. compiler bug on product of large integer constants on SPARC Submitter: Bennet Vance (bennet@cse.ogi.edu) Date: Jul 1, 1990 Version: 0.59 System: Sun 4/60 - SunOS Release 4.0.3c Severity: minor Problem: compiler bug on large products of integer constants Transcript: val it = () : unit - 2*268435455; val it = 536870910 : int - 2*268435456; Error: Compiler bug: [SparcCM.ashr] Status: fixed in 0.61 (jhr) -------------------------------------------------------------------------------- 245. NeXT installation problem Submitter: Lyman Taylor ( respond to lyman@portia.stanford.edu ) Date: 07/12/90 Version: 0.56 System: NeXT , 8M , hard disk , & OD ( build done on OD ) Severity: major Problem: install script does not excute Code: none Transcript: following ouput of makeml ( machine name helen ) helen> makeml -next makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.m68 mo makeml> (cd runtime; rm -f run allmo.o) makeml> (cd runtime; make MACHINE=M68 'DEFS= -DBSD -DNeXT -DRUNTIME=\"runtime\"' linkdata) cc -O -DM68 -DBSD -DNeXT -DRUNTIME=\"runtime\" -o linkdata linkdata.c makeml> runtime/linkdata [runtime/IntM68.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o makeml> (cd runtime; make MACHINE=M68 'DEFS= -DBSD -DNeXT' CPP=/lib/cpp 'CFL=' 'AS=as') cc -O -DM68 -DBSD -DNeXT -c run.c ml_os.h:113: can't find include file `sys/syscall.h' *** Exit 1 Stop. Comments: I'm not skilled at development for the NeXT. I was just looking to compile the latest version of SMLNJ so I could try it out there is an older version ( 0.43 ) on the Sparcs around here but the Next allows me to dump all this onto an OD so noone can complain about the space all the source is taking up. Status: fixed in 0.59 (jhr) -------------------------------------------------------------------------------- 246. repeated import consumes too much memory Submitter: Peter Canning <canning@hplabs.hp.com> Date: 27 June 1990 Version: 0.56 System: HP900S370 (m68030) HP-UX 7.0 Severity: major Problem: repeated use of the import facility causes the heap to grow Comments: In particular, if I repeatedly modify a file, import the file, then run the program defined in the file (the standard edit/compile/debug loop), my sml image seems to grow (and never shink again). When I was just using "use", sml would garbage collect freqently, but the process size would stay between 4000 and 5000 Kbytes. Using import (working on the same program), the process has grown as large as 11000 Kbytes. It appears that for some reason some data related to importing/compiling files is not being reclaimed by the garbage collector. Status: Fixed (defunct feature) -------------------------------------------------------------------------------- 247. close_out std_out Submitter: Mark R. Leone <mleone@cs.cmu.edu> Date: Fri, 29 Jun 90 16:09:02 EDT Version: 0.59 Problem: If standard output is closed, the top level exits ungracefully: Transcript: [r.ergo]/usr/mleone/sml/hypo-pl> sml Standard ML of New Jersey, Version 0.59, 4 June 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - close_out std_out; Uncaught exception Io with "output "<std_out>": closed outstream" Status: not a bug -------------------------------------------------------------------------------- 248. abstract types are not abstract Submitter: Dave MacQueen Date: 7/16/90 Version: 0.59 (0.57 and later) Severity: major Problem: Abstract types defined by abstype declarations are not made abstract (i.e. converted from DATAtyc to ABStyc form), and their equality property is not reset to NO. Equality properties of types defined in terms of the abstype are not recomputed (see bug 231.) Comments: After the abstype body has been processed, the concrete form of the abstract types must be replaced by the abstract form throughout the 'signature' of the exported bindings (values, constructors, types). Also equality properties of exported types have to be reevaluated. Currently, there is a function that attempts to transform the tycons in the type checker, but it affects only the abstract syntax, and not the static environment. The problem results from the removal of the ref around tycons in 0.57. Status: fixed in 0.64. -------------------------------------------------------------------------------- 249. separate compilation printing problems Submitter: Nick Rothwell <nick@lfcs.ed.ac.uk> (also Richard O'Neill) Date: 7/5/90 Version: 0.59 Severity: minor Problem: 0. If only one or other of the files exists (say, Foo.sml without Foo.bin or vice versa), the exception SystemCall gets raised. 1. The error message [Foo.bin is in the wrong format; recompiling] seems to have lost its closing "]" in 0.59. 2. The final bindings from a separately compiled module get printed on one line, as in: signature Asignature Bsignature Csignature D- rather than signature A signature B etc. Fix: (Richard O'Neill) For some reason the function printBindingTbl in print/printdec.sml was changed from its form in release 0.56 to a slightly modified forn in 0.59. The new form is functionally equivalent appart from omiting to generate newlines. Fix (currently untried): Return printBindingTbl to it 0.56 form. Status: fixed in 0.64(?) -------------------------------------------------------------------------------- 250. interpreter broken Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: Tue Jul 17 12:24:19 BST 1990 Version: 0.59 System: Sun3, SunOS 4.1 Severity: Major Problem: In interpret mode, version 0.59 fails with no explanation when compiling a grammar from mlyacc (slightly modified to use 'import'), whilst in compile mode, the grammar is compiled correctly. Version 0.56 does not exhibit the same problem. This seems a significant problem since using compile mode takes significant time and memory. Equally, I cannot use version 0.56 due to some of its bugs which manifest themselves when compiling other modules. I have not included the files as they are rather long (being an mlyacc generated parser and the relevant support files). I can supply you with a uuencoded compressed tar archive of them all if you desire. Transcript: unix% sml Standard ML of New Jersey, Version 0.59, 4 June 1990 - System.Control.interp; val it = ref true : bool ref - import "clean.grm"; [clean.grm.bin is out of date; recompiling] [reading clean.grm.sml] [reading lib/token.sig.bin... done] [closing clean.grm.sml] IMPORT failed (compile-time exception: SystemCall) - import "clean.grm"; [clean.grm.bin is out of date; recompiling] [reading clean.grm.sml] [reading lib/token.sig.bin... done] [reading clean.grm.sig.bin... done] [Major collection... 60% used (648480/1067380), 1900 msec] [Major collection... 96% used (1015412/1055228), 3000 msec] [Increasing heap to 3088k] [Major collection... 96% used (1526764/1586468), 4740 msec] [Increasing heap to 4640k] [Major collection... 96% used (2287536/2378284), 7480 msec] [Increasing heap to 6952k] [Major collection... [Increasing heap to 10528k] 96% used (3515248/3635044), 11120 msec] [Increasing heap to 10632k] [closing clean.grm.sml] IMPORT failed (compile-time exception: Cascade) - ^D unix% old-sml Standard ML of New Jersey, Version 0.56, 13 April 1990 val it = () : unit - System.Control.interp; val it = ref true : bool ref - import "clean.grm"; [clean.grm.bin is out of date; recompiling] [reading clean.grm.sml] [reading lib/token.sig.bin... ] [lib/token.sig.bin is the wrong format; recompiling] [closing lib/token.sig.bin] [reading lib/token.sig.sml] [reading lib/lrtable.sig.bin... ] [lib/lrtable.sig.bin is the wrong format; recompiling] [closing lib/lrtable.sig.bin] [reading lib/lrtable.sig.sml] [writing lib/lrtable.sig.bin... done] [closing lib/lrtable.sig.sml] [writing lib/token.sig.bin... done] [closing lib/token.sig.sml] [reading clean.grm.sig.bin... ] [clean.grm.sig.bin is the wrong format; recompiling] [closing clean.grm.sig.bin] [reading clean.grm.sig.sml] [reading lib/parserdata.sig.bin... ] [lib/parserdata.sig.bin is the wrong format; recompiling] [closing lib/parserdata.sig.bin] [reading lib/parserdata.sig.sml] [reading lib/token.sig.bin... ] [import(s) of lib/token.sig are out of date; recompiling] [closing lib/token.sig.bin] [reading lib/token.sig.sml] [reading lib/lrtable.sig.bin... done] [writing lib/token.sig.bin... done] [closing lib/token.sig.sml] [reading lib/lrtable.sig.bin... done] [writing lib/parserdata.sig.bin... done] [closing lib/parserdata.sig.sml] [writing clean.grm.sig.bin... done] [closing clean.grm.sig.sml] [Major collection... 66% used (1058292/1581868), 3360 msec] [Increasing heap to 3249k] [Major collection... 96% used (1629952/1687576), 5020 msec] [Increasing heap to 4929k] [Major collection... 96% used (2478864/2562240), 7800 msec] [Increasing heap to 7481k] [Major collection... 30% used (1226344/3978648), 4200 msec] [Decreasing heap to 4153k] [Major collection... 92% used (1982616/2147092), 6060 msec] [Increasing heap to 6081k] [Major collection... 85% used (2731764/3199400), 8480 msec] [Increasing heap to 8593k] [Major collection... 62% used (2809816/4478688), 9180 msec] [Increasing heap to 8657k] [Major collection... 60% used (2770384/4573952), 8920 msec] [Major collection... 62% used (2804296/4452412), 8980 msec] [Increasing heap to 8721k] [Major collection... 67% used (3031468/4473120), 8700 msec] [Increasing heap to 9033k] [writing clean.grm.bin... done] [closing clean.grm.sml] signature Clean_TOKENS signature TOKEN signature PARSER_DATA signature Clean_LRVALS signature LR_TABLE functor CleanLrValsFun - ^D unix% sml Standard ML of New Jersey, Version 0.59, 4 June 1990 - System.Control.interp := false; val it = () : unit - import "clean.grm"; [reading clean.grm.bin... ] [clean.grm.bin is the wrong format; recompiling [closing clean.grm.bin] [reading clean.grm.sml] [reading lib/token.sig.bin... ] [lib/token.sig.bin is the wrong format; recompiling [closing lib/token.sig.bin] [reading lib/token.sig.sml] [reading lib/lrtable.sig.bin... ] [lib/lrtable.sig.bin is the wrong format; recompiling [closing lib/lrtable.sig.bin] [reading lib/lrtable.sig.sml] [writing lib/lrtable.sig.bin... done] [closing lib/lrtable.sig.sml] [writing lib/token.sig.bin... done] [closing lib/token.sig.sml] [reading clean.grm.sig.bin... ] [clean.grm.sig.bin is the wrong format; recompiling [closing clean.grm.sig.bin] [reading clean.grm.sig.sml] [reading lib/parserdata.sig.bin... ] [lib/parserdata.sig.bin is the wrong format; recompiling [closing lib/parserdata.sig.bin] [reading lib/parserdata.sig.sml] [reading lib/token.sig.bin... done] [reading lib/lrtable.sig.bin... done] [writing lib/parserdata.sig.bin... done] [closing lib/parserdata.sig.sml] [writing clean.grm.sig.bin... done] [closing clean.grm.sig.sml] [Major collection... 61% used (679180/1109552), 2060 msec] [Increasing heap to 2240k] [Major collection... 80% used (932040/1158752), 2780 msec] [Increasing heap to 2848k] [Major collection... 95% used (1403328/1463408), 4240 msec] [Increasing heap to 4272k] [Major collection... 96% used (2109420/2194020), 6680 msec] [Increasing heap to 6408k] [Major collection... [Increasing heap to 9656k] 96% used (3255168/3361612), 10700 msec] [Increasing heap to 9824k] [Major collection... 36% used (1914068/5201708), 6400 msec] [Decreasing heap to 6208k] [Major collection... 85% used (2811340/3298792), 8620 msec] [Increasing heap to 8816k] [Major collection... 61% used (2810740/4607236), 8320 msec] [Major collection... 63% used (2882812/4569184), 8900 msec] [Increasing heap to 8928k] [Major collection... 57% used (2705236/4669212), 8360 msec] [Major collection... 61% used (2854268/4612180), 8560 msec] [writing clean.grm.bin... done] [closing clean.grm.sml] signature Clean_TOKENSsignature TOKENsignature PARSER_DATAsignature Clean_LRVALSsignature LR_TABLEfunctor CleanLrValsFun- Comment: import and interpreter mode are currently incompatible Status: not a bug ------------------------------------------------------------------------------- 251. omits tests for repeated bindings Submitter: Dave Berry db@lfcs.ed.ac.uk Date: 18th July 1990 Version: 0.59 System: All (I presume; actually tested on a Sun 3 with SunOS 4.0) Severity: minor Problem: omits tests for repeated bindings Code: type t = int and t = string; exception E and E; val rec f = fn x => x + 1 and f = fn n => if n > 0 then 1 else n * f (n - 1); Transcript: - type t = int and t = string; type t = int type t = string - exception E and E; exception E exception E - val rec f = fn x => x + 1 = and f = fn n => if n > 0 then 1 else n * f (n - 1); val f = fn : int -> int val f = fn : int -> int Comments: I expect that few people would make these mistakes in "real" code, but they might be more common when teaching. The tests are made for repeated constructors in a datatype, and in some (non-recursive?) value bindings, e.g. - datatype a = A | A; std_in:3.14-3.18 Error: duplicate constructor name - val a = 1 and a = 2; std_in:2.5-2.19 Error: duplicate variable-name `a' in pattern(s) Page 9 is the relevant part of the definition. Status: fixed in 0.65 -------------------------------------------------------------------------------- 252. include broken in 0.59 Submitter: Nick Date: 17 July '90 Version: 0.59 System: Irrelevant Severity: Major Problem: Inclusion of signatures with shared types: >Blam!<. Code: signature SIG1 = sig type ty sharing type ty = int end; signature SIG2 = sig include SIG1 end; Transcript: signature SIG1 = sig eqtype ty end Error: Compiler bug: Parse.includeSig.newTyc Comments: Works in 0.56 (which has different problems - see a previous report). Status: fixed in 0.64 -------------------------------------------------------------------------------- 253. SML Dumping core compiling mlyacc with -pervshare Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: Wed Jul 18 16:18:47 BST 1990 Version: 0.59 System: Sun3/50, SunOS 4.1 Severity: You decide... Problem: Attempting to compile mlyacc (as supplied with version 0.56 of SML of NJ) with a '-pervshare' version of SML of NJ 0.59 causes a Segmentation Fault. This does not seem to happen with the sharable SML compiler. I have the core dump if that would help... Status: fixed sometime between 0.59 and 0.74 -------------------------------------------------------------------------------- 254. failure to detect type error Submitter: Andrew Appel Date: 7/23/90 Version: 0.60 Severity: critical Problem: type error not detected Code: signature SIG = sig type EA val fopt : ((EA * EA) -> unit) option end functor CPSgen(M: SIG) : sig end = struct val g = case M.fopt of SOME f => let fun h x = f (x,x) in h end val x = g 2 end Comments: Caused by missing case in scan function in the definition of Unify.instantiate. Status: fixed in 0.61 (dbm) -------------------------------------------------------------------------------- 255. space leak with redeclaration of variables Submitter: John Reppy Date: 7/24/90 Version: 0.60 Severity: major Problem: I think that there is a space leak in the top-level loop/environment. If I keep redefining the same identifiers, the amount of live data grows, when it should be fairly constant. I assume that the problem is that the top-level symbol table is holding onto something it shouldn't. Transcript: Here is a simple demonstration of the space leak (60 bytes/iteration): Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (516680/526692), 610 msec] structure S : sig end - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (517100/525980), 550 msec] structure S : sig end - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (517160/526388), 550 msec] structure S : sig end - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (517220/526448), 550 msec] structure S : sig end - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (517280/526508), 540 msec] structure S : sig end Comment: (appel) This is the top-level line-number information, and is a few bytes per line, regardless of size of defined structures. Status: fixed in 0.65 (actually, it's now a 48-byte leak) ------------------------------------------------------------------------------- 256. mcopt compiler bug with improper function definition Submitter: John Mitchell (jcm@iswim.stanford.edu) Date: 7/24/90 Version: 0.60 Severity: critical Problem: Compiler bug "r_o in mcopt" raised as a result of improper clausal function definition. Transcript: - datatype 'a stack = empty | stk of 'a *'a stack; datatype 'a stack con empty : 'a stack con stk : 'a * 'a stack -> 'a stack - fun pop stk(e,s) = s; Error: Compiler bug: r_o in mcopt adding parens fixes the problem, so not serious as is: fun pop (stk (e,s)) = s; std_in:2.5-2.23 Warning: match not exhaustive stk (e,s) => ... val pop = fn : 'a stack -> 'a stack Submitter: Sergio Antoy, antoy@vtodie.cs.vt.edu Date: 8/9/90 Version: SML of NJ version number 056 System: DEC3100 V2.2 (Rev. 15) Severity: Problem: "using" following file sml generates "Compiler bug" msg Code: datatype 'a Xlist = Xnil | Xcons of 'a * 'a Xlist | Xappend of 'a Xlist * 'a Xlist; fun incr Xappend(Xnil,Xnil) = Xnil | incr Xappend(Xnil,Xcons(a,b)) = Xcons(a,b); Transcript: goliat[8]% sml Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - use "trans.sml"; [opening trans.sml] datatype 'a Xlist con Xappend : 'a Xlist * 'a Xlist -> 'a Xlist con Xcons : 'a * 'a Xlist -> 'a Xlist con Xnil : 'a Xlist Error: Compiler bug: r_o in mcopt [closing trans.sml] - Status: fixed in 0.62? -------------------------------------------------------------------------------- 257. Compiler bug: EnvAccess.lookPath with imported functors (bug 214 again) Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: Mon Jul 30 11:52:10 BST 1990 Version: 0,59, 0.60 System: Sun3/180, SunOS 4.1 Severity: Major Problem: Bug #214 ('Compiler bug: EnvAccess.lookPath occurs when printing a top level result') has not been laid to rest, it still occurs with imported functors. Transcript: unix% cat > one.sml functor classes () = struct datatype symbol_class = DataClass of data_class | SpecialClass of special_class and data_class = Int | Real | Bool | String and special_class = Any | None end ^D unix% cat > two.sml signature classes = sig datatype symbol_class = DataClass of data_class | SpecialClass of special_class and data_class = Int | Real | Bool | String and special_class = Any | None end functor nodes ( structure Classes : classes ) = struct structure Classes = Classes local open Classes in datatype node = ClassNode of symbol_class | ValueNode of data_class end end ^D unix% sml Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "one" "two"; [reading one.sml] [writing one.bin... done] [closing one.sml] functor classes [reading two.sml] [writing two.bin... done] [closing two.sml] signature classes functor nodes - structure Classes = classes () = structure Nodes = nodes ( structure Classes = Classes ) = open Classes Nodes ; structure Classes : sig datatype special_class con Any : special_class con None : special_class datatype symbol_class con DataClass : data_class -> symbol_class con SpecialClass : special_class -> symbol_class datatype data_class con Bool : data_class con Int : data_class con Real : data_class con String : data_class end structure Nodes : sig structure Classes : sig...end datatype node con ClassNode : symbol_class -> node con ValueNode : data_class -> node end open Classes Nodes - ClassNode (DataClass Int); val it = ClassNode Error: Compiler bug: EnvAccess.lookPath - ValueNode Int; val it = ValueNode Int : node - ^D unix% sml Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - app use ["one.sml","two.sml"]; [opening one.sml] functor classes : <sig> [closing one.sml] [opening two.sml] signature classes = sig datatype special_class con Any : special_class con None : special_class datatype symbol_class con DataClass : data_class -> symbol_class con SpecialClass : special_class -> symbol_class datatype data_class con Bool : data_class con Int : data_class con Real : data_class con String : data_class end functor nodes : <sig> [closing two.sml] val it = () : unit - structure Classes = classes () = structure Nodes = nodes ( structure Classes = Classes ) = open Classes Nodes ; structure Classes : sig datatype special_class con Any : special_class con None : special_class datatype symbol_class con DataClass : data_class -> symbol_class con SpecialClass : special_class -> symbol_class datatype data_class con Bool : data_class con Int : data_class con Real : data_class con String : data_class end structure Nodes : sig structure Classes : sig...end datatype node con ClassNode : symbol_class -> node con ValueNode : data_class -> node end open Classes Nodes - ClassNode (DataClass Int); val it = ClassNode (DataClass Int) : node - ValueNode Int; val it = ValueNode Int : node - ^D -------------------------------------------------------------------------------- 258. System.Directory.cd failure Submitter: Dave MacQueen Date: 8/15/90 Version: 0.63 Problem: System.Directory.cd applied to nonexistent directory name raises uncaught exception Transcript: - System.Directory.cd "foo"; uncaught exception SysError - Status: fixed in 0.65 -------------------------------------------------------------------------------- 259. uncaught exception Match compiling normperv.sml Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: Tue Aug 14 10:04:21 BST 1990 Version: 0.63 (not in 0.62 or earlier) System: Sun3/180, SunOS 4.1 Severity: Critical Problem: Version 0.63 has a new bug whereby it cannot compile dbguser/normperv.sml This prevents creating the '-debug' version. Transcript: unix% sml Standard ML of New Jersey, Version 0.63, 10 August 1990 val it = () : unit - use "dbguser/normperv.sml"; [opening dbguser/normperv.sml] [closing dbguser/normperv.sml] uncaught exception Match - Comments: Smlc, version 0.62, created the 680X0 '.mo' files from which a -pervshare runtime system was built using gcc. This runtime system was then used to build a normal and then a -debug system (which failed). I've marked the severity as critical because it is a critical problem for this version. For me however, its not so critical as I seem to be managing OK with 0.62. Status: apparently fixed as of 0.75 -------------------------------------------------------------------------------- 260. failure to raise overflow Submitter: David.Tarditi@B.GP.CS.CMU.EDU Date: Mon, 13 Aug 90 15:43:26 EDT Version: 0.63? Problem: The following program should raise an Overflow exception on all 32-bit 2's complement machines but it doesn't: ------- fun exp 0 = 1 | exp i = 2 * exp (i-1); val a = exp 29; val minint = ~a + ~a; (* should raise overflow *) val test = minint div ~1; ------- An overflow exception was not raised in version 0.59 on a Sun 3 running Mach emluating 4.3 BSD. It was raised in version 0.59 on a MicroVax 3 running Mach emulating 4.3 BSD. Comments: This is the only case where overflow can occur in division. It occurs since MININT = -(MAXINT+1) in 2's complement. Division of MININT by -1 causes an overflow. Status: fixed in 0.64 ------------------------------------------------------------------------------- 261. Compiler Bug: abstractBody.abstractType 1 (assumed same as 234) Submitter: George Beshers, beshers@sun2.brc.uconn.edu Date: Aug 9, 1990 Version: 0.56, sparc Severity: Significant Problem: Compiler generates ``Regex.sml:21.17 Compiler Bug: abstractBody.abstractType 1'' Note: this is somewhat delicate to reproduce. If you break the following into files and start a clean sml and do "use Regex.sml;" it consistently generates the error. However, if you *repeat* the use Regex.sml it compiles (however I have a lingering suspision about the correctness of the code produced...). On one occasion I tried "using" all the files in sequence and that worked OK, at least the working parts of the module did. Also I have tried to cut parts of the Regex.sml file and reproduce the error but without success. In particular, the error is dependent on at least some of the code appearing later in the file. Code: (*---------------------------- Ordinal.sml ---------------------*) signature ORD_RANGE = sig type elem val ord : elem -> int and de_ord : int -> elem end functor NatFn() : ORD_RANGE = struct type elem = int fun ord x = x fun de_ord x = x end functor CharFn() : ORD_RANGE = struct type elem = string val ord = String.ord val de_ord = chr end (*------------------------ BitSet.sml ---------------------------*) import "Ordinal"; signature BITSET = sig structure Elem : ORD_RANGE exception NoSuchElement type bitset val empty: bitset and singleton : Elem.elem -> bitset and range : Elem.elem * Elem.elem -> bitset and setFromList : Elem.elem list -> bitset and exists : Elem.elem -> bitset -> bool and union : bitset * bitset -> bitset and intersect : bitset * bitset -> bitset and difference : bitset * bitset -> bitset val isempty : bitset -> bool and eq : bitset * bitset -> bool and subset : bitset * bitset -> bool and subset': bitset * bitset -> bool val select : bitset * (Elem.elem -> bool) -> bitset val lowest : bitset -> Elem.elem val lowest' : bitset -> Elem.elem -> Elem.elem val highest : bitset -> Elem.elem val highest' : bitset -> Elem.elem -> Elem.elem val totOrder : bitset * bitset -> bool val forall : bitset -> Elem.elem list val makeString : bitset -> string end; (* trivialized version *) functor BitSetFn(Elem1 : ORD_RANGE) : BITSET = struct structure Elem = Elem1 local open Elem Bits val bits_per_int = 30; val all_bits = 1073741823 (* 077777777777 *) in datatype bitset = BS of {lo : int, hi : int, setx : int array} val empty = BS{lo = 0, hi = ~1, setx = array(0, 0)} fun singleton x = empty fun range(l, h) = empty fun exists x (BS{lo, hi, setx}) = false fun union(set1, set2) = empty exception NoSuchElement fun lowest (BS{lo,...}) = de_ord lo fun lowest' (BS{lo,...}) start = de_ord lo fun highest (BS{hi,...}) = de_ord hi fun highest' (BS{hi,...}) start = de_ord hi fun reduce bs = empty fun intersect(set1, set2) = empty fun difference(set1, set2) = empty fun isempty (BS{lo, hi,...}) = hi < lo fun eq (set1, set2) = true fun op subset(s1, s2) = isempty (reduce (difference (s1, s2))) fun op subset'(s1, s2) = isempty (reduce (difference (s1, s2))) andalso (not (isempty (reduce (difference (s2, s1))))) fun lowQuery (bs, q) = let val BS{lo, hi, setx} = bs val i = ref lo in de_ord (!i) end fun highQuery (bs, q) = let val BS{lo, hi, setx} = bs val i = ref hi in de_ord (!i) end fun select (bs, q) = bs fun totOrder (set1, set2) = true fun forall s = nil fun makeString s = "" fun setFromList (l' : Elem.elem list) = empty end end (*------------------------------ RedBlack.sml ------------------*) signature RED_BLACK = sig type tree type key val empty : tree val insert : key * tree -> tree val lookup : key * tree -> key exception notfound of key end functor RedBlack(B : sig type key val > : key*key->bool end): RED_BLACK = struct open B datatype color = RED | BLACK datatype tree = empty | tree of key * color * tree * tree exception notfound of key fun insert (key,t) = let fun f empty = tree(key,RED,empty,empty) | f (tree(k,BLACK,l,r)) = if key>k then case f r of r as tree(rk,RED, rl as tree(rlk,RED,rll,rlr),rr) => (case l of tree(lk,RED,ll,lr) => tree(k,RED,tree(lk,BLACK,ll,lr), tree(rk,BLACK,rl,rr)) | _ => tree(rlk,BLACK,tree(k,RED,l,rll), tree(rk,RED,rlr,rr))) | r as tree(rk,RED,rl, rr as tree(rrk,RED,rrl,rrr)) => (case l of tree(lk,RED,ll,lr) => tree(k,RED,tree(lk,BLACK,ll,lr), tree(rk,BLACK,rl,rr)) | _ => tree(rk,BLACK,tree(k,RED,l,rl),rr)) | r => tree(k,BLACK,l,r) else if k>key then case f l of l as tree(lk,RED,ll, lr as tree(lrk,RED,lrl,lrr)) => (case r of tree(rk,RED,rl,rr) => tree(k,RED,tree(lk,BLACK,ll,lr), tree(rk,BLACK,rl,rr)) | _ => tree(lrk,BLACK,tree(lk,RED,ll,lrl), tree(k,RED,lrr,r))) | l as tree(lk,RED, ll as tree(llk,RED,lll,llr), lr) => (case r of tree(rk,RED,rl,rr) => tree(k,RED,tree(lk,BLACK,ll,lr), tree(rk,BLACK,rl,rr)) | _ => tree(lk,BLACK,ll,tree(k,RED,lr,r))) | l => tree(k,BLACK,l,r) else tree(key,BLACK,l,r) | f (tree(k,RED,l,r)) = if key>k then tree(k,RED,l, f r) else if k>key then tree(k,RED, f l, r) else tree(key,RED,l,r) in case f t of tree(k,RED, l as tree(_,RED,_,_), r) => tree(k,BLACK,l,r) | tree(k,RED, l, r as tree(_,RED,_,_)) => tree(k,BLACK,l,r) | t => t end fun lookup (key,t) = let fun look empty = raise (notfound key) | look (tree(k,_,l,r)) = if k>key then look l else if key>k then look r else k in look t end end (*------------------------ Regex.sml ------------------------*) import "Ordinal"; import "BitSet"; import "RedBlack"; signature CHAR_REG_EXP = sig structure Alphabet : ORD_RANGE structure AlphaSet : BITSET structure range : ORD_RANGE structure Set : BITSET sharing type Set.Elem.elem = range.elem = int type pattern datatype Ch_Reg_Exp = CONCAT of Ch_Reg_Exp list | ALTERNATE of Ch_Reg_Exp list | STAR of Ch_Reg_Exp | PLUS of Ch_Reg_Exp | OPTION of Ch_Reg_Exp | LETTER of AlphaSet.bitset | AUG (* For internal use only *) type Aug_Reg_Exp val re_to_Aug : Ch_Reg_Exp -> {aug_re : Aug_Reg_Exp, count : int, leafList : Aug_Reg_Exp list} val Aug_to_Follow : {aug_re : Aug_Reg_Exp, count : int, leafList : Aug_Reg_Exp list} -> Set.bitset array val Build_FSM : {aug_re : Aug_Reg_Exp, count : int, leafList : Aug_Reg_Exp list} * Set.bitset array -> pattern val Print : Aug_Reg_Exp -> unit end functor Reg_ExpFn() (* : CHAR_REG_EXP *) = struct structure Alphabet = CharFn() structure AlphaSet : BITSET = BitSetFn(Alphabet) structure range = NatFn() structure Set : BITSET = BitSetFn(range) type InfoTy = { fp : Set.bitset, lp : Set.bitset, null : bool } datatype pattern = Pat datatype Ch_Reg_Exp = CONCAT of Ch_Reg_Exp list | ALTERNATE of Ch_Reg_Exp list | STAR of Ch_Reg_Exp | PLUS of Ch_Reg_Exp | OPTION of Ch_Reg_Exp | LETTER of AlphaSet.bitset | AUG (* Internal use only *) datatype Aug_Reg_Exp = AugCONCAT of InfoTy * Aug_Reg_Exp list | AugALTERNATE of InfoTy * Aug_Reg_Exp list | AugSTAR of InfoTy * Aug_Reg_Exp | AugPLUS of InfoTy * Aug_Reg_Exp | AugOPTION of InfoTy * Aug_Reg_Exp | AugLETTER of InfoTy * AlphaSet.bitset | AugAUG of InfoTy fun mkInfo () = { Fpos = Set.empty, Lpos = Set.empty, Nullable = false } fun info (AugCONCAT(inf, _)) = inf | info (AugALTERNATE(inf, _)) = inf | info (AugSTAR(inf, _)) = inf | info (AugPLUS(inf, _)) = inf | info (AugOPTION(inf, _)) = inf | info (AugLETTER(inf, _)) = inf | info (AugAUG(inf)) = inf (* type 'a Aug = {aug_re : Aug_Reg_Exp, count : int, leafList : Aug_Reg_Exp list} *) fun re_to_Aug re = let fun app_map cnt nil = (nil : Aug_Reg_Exp list, cnt, nil) | app_map cnt (hd::tl) = let val hd' = pass1(cnt, hd) val {aug_re=ar, count=c, leafList=le} = hd' val (arTl, cntTl, leTl) = app_map c tl in (ar::arTl, cntTl, le@leTl) end and pass1 (counter, CONCAT(re_l)) = let val (ar', cnt', le') = app_map counter re_l fun foldConcat (a, b) = let val {fp = fpA, lp = lpA, null = nuA} = a val {fp = fpB, lp = lpB, null = nuB} = b val n = nuA andalso nuB val fp' = if nuB then Set.union (fpA, fpB) else fpB val lp' = if nuA then Set.union (lpA, lpB) else lpA in print "foldConcat\n"; print " given A "; print " fpA="; print (Set.makeString fpA); print " lpA="; print (Set.makeString lpA); print nuA; print "\n"; print " given B "; print " fpB="; print (Set.makeString fpB); print " lpB="; print (Set.makeString lpB); print nuB; print "\n"; print " results "; print " fp'="; print (Set.makeString fp'); print " lp'="; print (Set.makeString lp'); print n; print "\n"; {fp = fp', lp = lp', null = n} end val base = {fp = Set.empty, lp = Set.empty, null = true} val _ = (print " base "; print " fp'="; print (Set.makeString (#fp base)); print " lp'="; print (Set.makeString (#lp base)); print (#null base); print "\n") val info = revfold foldConcat (map info ar') base in {aug_re = AugCONCAT(info, ar'), count = cnt', leafList = le'} end | pass1 (counter, ALTERNATE(re_l)) = let val (ar', cnt', le') = app_map counter re_l fun foldAlt (a, b) = let val {fp = hdA, lp = lpA, null = nuA} = a val {fp = hdB, lp = lpB, null = nuB} = b in {fp = Set.union (hdA, hdB), lp = Set.union (lpA, lpB), null = nuA orelse nuB} end val base = {fp = Set.empty, lp = Set.empty, null = false} val info = fold foldAlt (map info ar') base in {aug_re = AugALTERNATE(info, ar'), count = cnt', leafList = le'} end | pass1 (counter, STAR(re)) = let val {aug_re=ar, count=c, leafList=le} = pass1(counter, re) val {fp = fp', lp = lp', null = nu} = info ar val info = {fp = fp', lp = lp', null = true} in {aug_re = AugSTAR(info, ar), count = c, leafList = le} end | pass1 (counter, PLUS(re)) = let val {aug_re=ar, count=c, leafList=le} = pass1(counter, re) val {fp = fp', lp = lp', null = nu} = info ar val info = {fp = fp', lp = lp', null = nu} in {aug_re = AugPLUS(info, ar), count = c, leafList = le} end | pass1 (counter, OPTION(re)) = let val {aug_re=ar, count=c, leafList=le} = pass1(counter, re) val {fp = fp', lp = lp', null = nu} = info ar val info = {fp = fp', lp = lp', null = true} in {aug_re = AugOPTION(info, ar), count = c, leafList = le} end | pass1 (counter, LETTER(a)) = let val c = Set.singleton counter val info = {fp = c, lp = c, null = false} val aug_r = AugLETTER(info, a) in {aug_re = aug_r, count = counter+1, leafList = [aug_r]} end | pass1 (counter, AUG) = let val c = Set.singleton counter val info = {fp = c, lp = c, null = false} val aug_r = AugAUG(info) in {aug_re = aug_r, count = counter+1, leafList = [aug_r]} end in pass1 (0, CONCAT [re, AUG]) end fun prFollow fp = let val l = Array.length fp fun prx i = (print i; print " "; print (Set.makeString (fp sub i)); print "\n") fun p i = if i < l then (prx i; p (i + 1)) else () in p 0 end fun Aug_to_Follow {aug_re, count, leafList} = let val followPos = array(count, Set.empty) val count = ref 0 fun updSet fp i = update(followPos, i, Set.union(followPos sub i, fp)) fun pass2 (AugCONCAT(inf, re_l)) = let fun foldConcat (x, y) = let val updList = Set.forall y val {fp, lp, ...} = info x val updSet' = updSet fp fun ms nil = "" | ms (x::y) = (makestring x) ^ (ms y) in print ("[" ^ (ms updList) ^ "]" ^ "\n"); print (Set.makeString lp ^ "\n"); app updSet' updList; lp end val c = !count in inc count; print "before fold "; print c; print "\n"; prFollow followPos; print "\n"; revfold foldConcat re_l Set.empty; print "after fold "; print c; print "\n"; prFollow followPos; print "\n"; app pass2 re_l; print "after app "; print c; print "\n"; prFollow followPos; print "\n" end | pass2 (AugALTERNATE(inf, re_l)) = app pass2 re_l | pass2 (AugSTAR(inf, re)) = let val {fp, lp, ...} = info re val updSet' = updSet fp in app updSet' (Set.forall lp); pass2 re end | pass2 (AugPLUS(inf, re)) = let val {fp, lp, ...} = info re val updSet' = updSet fp in app updSet' (Set.forall lp); pass2 re end | pass2 (AugOPTION(inf, re)) = pass2 re | pass2 (AugLETTER(inf, _)) = () | pass2 (AugAUG(inf)) = () in pass2 aug_re; followPos end datatype transition = TR of AlphaSet.bitset * state and state = ST of {posSet : Set.bitset, stId : int, trans : transition list} fun le (ST{posSet = pS1,...}, ST{posSet = pS2,...}) = Set.totOrder (pS1, pS2) fun getPosSet (ST{posSet,...}) = posSet structure table = RedBlack(struct type key = state val op > = le end) fun Build_FSM ({aug_re, count, leafList}, followPos) = let (* get character set at position i *) fun cSetAt i = case nth (leafList, i) of AugLETTER(inf, x) => x | AugAUG(_) => AlphaSet.empty (* test to see if character has transition at position i *) fun atPos c i = AlphaSet.exists c (cSetAt i) (* Is this position a final position *) fun final i = case nth (leafList, i) of AugAUG(_) => true | _ => false (* return only those elements which match query *) fun sublist query l = let fun ss nil = nil | ss (hd::tl) = let val x = (ss tl) in if query hd then hd::x else x end in ss l end val cnt = ref 1 fun build_auto states unmarked = if unmarked = nil then states else let val T = hd unmarked val _ = print ("build_auto " ^ (Set.makeString T) ^ "\n") val allchar = let fun f (i, x) = AlphaSet.union(cSetAt i, x) in fold f (Set.forall T) AlphaSet.empty end val _ = print (" allchar = " ^ (AlphaSet.makeString allchar) ^ "\n"); fun eachChar states unmarked trans allchar = if AlphaSet.isempty allchar then (states, unmarked, trans) else let val _ = print "eachChar\n" fun next cSet = let val x = AlphaSet.lowest cSet val _ = print ("next cSet=" ^ (AlphaSet.makeString cSet) ^ " ") val _ = print (makestring (AlphaSet.Elem.ord x) ^ "\n") val posSet = Set.select (T, atPos x) val _ = print "Check\n" fun findSet i ch = if i = count then ch else let val y = if Set.exists i posSet then AlphaSet.intersect(ch, cSetAt i) else AlphaSet.difference(ch, cSetAt i) in findSet (i + 1) y end in (findSet 0 cSet, posSet) end (* next *) val (cSet, posSet) = next allchar val _ = print (" cSet=" ^ (AlphaSet.makeString cSet) ^ ", posSet = " ^ (Set.makeString posSet) ^ "\n") fun makeU s = let fun f (i, x) = Set.union (followPos sub i, x) in fold f (Set.forall posSet) Set.empty end (* makeU *) val U = makeU posSet val _ = print (" U=" ^ (Set.makeString U) ^ "\n") fun FindInsert st u = let val dummy = ST{posSet = u, stId = 0, trans = []} in (table.lookup(dummy, st), st, unmarked) handle table.notfound _ => let val u' = ST{posSet = u, stId = !cnt, trans=[]} val st' = table.insert(u', st) in inc cnt; (u', st', unmarked@[u]) end end (* FindInsert *) val (ToState, states', unmarked') = FindInsert states U val trans' = TR(cSet, ToState)::trans in eachChar states' unmarked' trans' (AlphaSet.difference (allchar, cSet)) end (* eachChar *) val (states', unmarked', trans') = eachChar states unmarked [] allchar val dummy = ST{posSet = T, stId = 0, trans = []} val ST{stId = Tid,...} = table.lookup(dummy, states') val s = ST{posSet = T, stId = Tid, trans = trans'} val states2 = table.insert(s, states') in build_auto states' (tl unmarked') end (* build_auto *) val {fp = st',...} = info aug_re val startstate = ST{posSet = st', stId = 0, trans = []} val stTable = table.insert (startstate, table.empty) val autoList = build_auto stTable [st'] in autoList end fun Print re = let val depth = ref 0 fun printInfo ({fp, lp, null} : InfoTy) = ( print "Fpos="; print (Set.makeString (fp)); print " Lpos="; print (Set.makeString (lp)); if null then print " nullable\n" else print "\n" ) fun Pr (AugCONCAT(inf, re_l)) = ( print "CONCAT "; printInfo inf; app Pr1 re_l ) | Pr (AugALTERNATE(inf, re_l)) = ( print "ALTERN "; printInfo inf; app Pr1 re_l ) | Pr (AugSTAR(inf, re)) = ( print "KLEENE "; printInfo inf; Pr1 re ) | Pr (AugPLUS(inf, re)) = ( print "POSITV "; printInfo inf; Pr1 re ) | Pr (AugOPTION(inf, re)) = ( print "OPTION "; printInfo inf; Pr1 re ) | Pr (AugLETTER(inf, _)) = ( print "LETTER "; printInfo inf ) | Pr (AugAUG(inf)) = ( print "AUGMEN "; printInfo inf ) and Pr1 x = let val i = ref 0; in ( while (!i) < (!depth) do (print " "; inc i); inc depth; Pr x; dec depth ) end in Pr1 re end; end; structure RRP_Test = Reg_ExpFn(); open RRP_Test; val a = LETTER(AlphaSet.singleton "a") val b = LETTER(AlphaSet.singleton "b") val c = LETTER(AlphaSet.singleton "c") val d = LETTER(AlphaSet.singleton "d") val a_b_c = ALTERNATE([a, b, c]); val aug = re_to_Aug a_b_c; Print (#aug_re aug); val fol = Aug_to_Follow aug; prFollow fol; print "Before Build_FSM\n"; val t = Build_FSM(aug, fol); print "\n\n\n"; val abc = CONCAT([a, b, c]); val aug' = re_to_Aug abc; Print (#aug_re aug'); val fol' = Aug_to_Follow aug'; prFollow fol'; val t' = Build_FSM(aug', fol'); Status: fixed in 0.64 ------------------------------------------------------------------------------- 262. Using the LIBRARY with v0.62 Submitter: "Soren P. Christensen" <schristensen@daimi.aau.dk> Date: Wed, 8 Aug 90 14:28:49 +0200 Problem: I just tried to build the library found in /dist/ml/LIBRARY.tar.Z and this fails. We are using a spark version of 0.62. I am not dependent on the Library and the reson I report this is only so that you can use it in your testing. I had to make small changes like the definition of the quit function by means of cleanup. 1) There seems to be problems with the exceptions. --------------- Transcript: Standard ML of New Jersey, Version 0.62, 1 August 1990 val it = () : unit - fn () => (() handle Interrupt=>()); val it = fn : unit -> unit - exception xx = Interrupt; std_in:3.16-3.24 Error: unbound exn: Interrupt - raise Interrupt; std_in:1.7-1.15 Error: unbound variable Interrupt std_in:1.1-1.15 Error: argument of raise is not an exception raised: undef in expression: raise Interrupt ---------------- 2) later on it terminates with a runbind, I think this is related to the exceptions too. Comments: (1) The Interrupt exception constructor has gone away, and Interrupt handling should be replaced by handling the interrupt signal. (2) The runbind exception seems to be a genuine bug. Status: fixed in 0.65 ------------------------------------------------------------------------------- 263. problem with input via datakit con Submitter: pjw Date: 8/8/90 Transcript: con tempel connected to tempel.mesgdcon on /net/dk/4 $ cd /usr/dbm/sml/60/src $ sml Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - -3; std_in:2.1 Error: nonfix identifier required std_in:2.1-2.2 Error: operator and operand don't agree (tycon mismatch) operator domain: 'Z * 'Z operand: int in expression: - 3 std_in:2.1 Error: overloaded variable "-" cannot be resolved uncaught Io exception (Loader): input "<std_in>": negative character count $ Status: fixed in 0.65 -------------------------------------------------------------------------------- 264. No type-explicitness check in nj-sml Submitter: David Turner <dnt@lfcs.edinburgh.ac.uk> Date: 7/8/90 Version : SML of NJ 0.56 and 0.59 System : Sun Severity : Dunno, but its pretty anti-social Problem : The compiler doesn't seem to check for type explicitness in signatures (see section 5.8 and also rule 65 of the ML definition). This means many signatures which can never be matched are still accepted as valid signatures. Transcript : - signature X = sig type t val x : t type t end; signature X = sig type t val x : ?.t end Status: fixed in 0.73 -------------------------------------------------------------------------------- 265. strong type variables accepted in exception declarations Submitter: Dave Berry, db@lfcs.ed.ac.uk Date: Aug 7 1990 Version: 0.56, 0.59 Severity: Minor (although it presumably means that the type system can be broken!) Problem: The compiler doesn't reject applicative type variables in exception declarations. Code: val id: 'a -> 'a = let exception dummy of 'a in fn x => x end; Transcript: The above code produces: val id = fn : 'a -> 'a Status: fixed in 0.65 -------------------------------------------------------------------------------- 266. uncaught Io exception in use From: John Reppy Date: Mon, 6 Aug 90 18:53:48 EDT System: 0.62 Problem: I've noticed the following new (I think) bug. An Io error in use results in an uncaught exception. Standard ML of New Jersey, Version 0.62, 1 August 1990 val it = () : unit - use "foo"; [cannot open foo] uncaught exception Io "open_in "foo": open failed, No such file or directory" The problem is that in "use_file" in build/interact.sml (line 307), the exception Io gets re-raised. Was this changed for the debugger? [dbm, 8/30/90] Fixed so that exceptions are handled even for nonterminal input. Status: fixed in 0.65 ------------------------------------------------------------------------------- 267. sharing again From: Simon Finn <simon@abstract-hardware-ltd.co.uk> Date: Thu, 2 Aug 90 10:48:47 BST Version: d64 Problem: The following program breaks Poly/ML v1.88 and NJML v0.44a (the most recent version to which I have access) [breaks d64 as well]. Code: signature S1 = sig eqtype t val x : t end; signature S2 = sig structure A : sig end structure C : sig structure A : S1 end sharing A = C.A end; functor F(structure A:S1 structure B:S2 sharing A = B.A) = struct val y = (A.x = B.C.A.x) end; Transcript: Standard ML of New Jersey, Version d64, ? August 1990 val it = () : unit - signature S1 = sig eqtype t val x : t end signature S2 = sig structure A : sig...end structure C : sig...end end std_in:21.11-21.25 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.t * ?.t operand: ?.t * ?.t in expression: = (A.x,B.C.A.x) Comment: This program is valid, since structure A shares with B.A which shares with B.C.A, hence A.t and B.C.A.t must be the same (equality) type. However: Status: fixed in 0.73 -------------------------------------------------------------------------------- 268. import, equality Submitter: Jason Fischl <fischl@cpsc.ucalgary.ca> Date: April 9, 1990 Version: 0.44 System: Sparcstation 1 Severity: major Problem: The module system has a bug in it with regard to equality types (I think). The following is a pretty concise description of what will cause the bug to occur. Code: (*-----------------FILE: term.sig.sml----------------------*) signature termsig = sig datatype term = Const of string | Var of string | Func of string * term list end; (*--------------FILE: term.sml-------------------------*) import "term.sig"; functor termFC ():termsig = struct datatype term = Const of string | Var of string | Func of string * term list end; (*------------FILE: parse_term.sml---------------------------*) import "term.sig"; functor parse_termFC (structure TERM:termsig) = struct open TERM fun term_nil x = (x:term list) = [] end; (*---------------------------------------*) Transcript: - import "parse_term"; [parse_term.bin is out of date; recompiling] [reading parse_term.sml] [reading term.sig.bin... done] parse_term.sml, line 11: Error: Compiler bug: tycStamp equal: type = ?.term list import: code generation failed [closing parse_term.sml] IMPORT failed (codegen) - Comments: I couldn't find any reference to it in the bug reports so I had to assume it was all new. It would have been much nicer if the error message had been a bit more descriptive. All I knew was that it was a type problem. There was no info as to which line the error occurred on or which function or anything really. I would appreciate a reply at some point if you could manage since I am curious as to the nature of my problem. Undoubtedly it will get me again! Fix: In order to fix the problem I had to define the fun term_nil inside the term functor and then also put it in the termsig signature. This took me on the order of 8 hours to figure out! Status: fixed before 0.65 ------------------------------------------------------------------------------- 269. failure in abstractBody with embedded signature Submitter: Dave MacQueen Date: 8/29/90 Version: 0.63 Code: functor F() = struct datatype d = D structure A : sig type s val x : s * d end = struct datatype s = MKs val x = (MKs,D) end end; structure B = F(); val (_,B.D) = B.A.x; Transcript: - use "bug269.sml"; [opening bug269.sml] functor F : <sig> structure B : sig structure A : sig...end datatype d con D : d end bug269.sml:16.5-16.19 Error: pattern and expression in val dec don't agree (tycon mis match) pattern: B.A.s * B.d expression: B.A.s * ?.d in declaration: (_,D) = B.A.x [closing bug269.sml] Status: fixed in 0.65 ------------------------------------------------------------------------------- 270. Compiler bug: TypesUtil.lookTycPath: NULLstr Submitter: Dave MacQueen Date: 8/29/90 Version: 0.63 Problem: failure to interpret path for X.d in embedded signature Formal paramter X was not bound properly. Code: functor F(X: sig datatype d = A end) = struct structure S : sig val x : X.d end = struct val x = X.A end end Status: fixed in 0.65 ------------------------------------------------------------------------------- 271. secondary compiler bug Submitter: Gary T. Leavens leavens@bambam.cs.iastate.edu Date: 8/29/90 Version: 0.64 System: HP 9000/370, HP-UX 7.0 Severity: minor Problem: get compiler bug report Code: the following in a file "report" signature IntMapSig = sig type 'a map val apply: ('a map)*int -> 'a exception NotFound end; signature ValueSig = sig type value end; signature SymbolSig = sig type sym val hash: sym -> int end; functor SymTblFct(structure IntMap: IntMapSig structure Val: ValSig structure Sym: SymSig): sig type table exception Lookup val lookup: table * Sym.sym -> Val.value val update: table * Sym.sym * Val.value -> table end = struct datatype table = TBL of (Sym.sym * Val.value)list IntMap.map exception Lookup fun find(sym,[]) = raise Lookup | find(sym,(sym',v)::rest) = if sym = sym' then v else find(sym,rest); fun lookup(TBL map, s) = let val n = Sym.hash(s) val l = IntMap.apply(map,n) in find(s,l) end handle IntMap.NotFound => raise Lookup (* ... *) end; Transcript: a transcript of session illustrating problem follows Standard ML of New Jersey, Version 0.64, ? August 1990 val it = () : unit - [opening report] signature IntMapSig = sig type 'a map exception NotFound val apply : 'a map * int -> 'a end signature ValueSig = sig type value end signature SymbolSig = sig type sym val hash : sym -> int end report:20.20-20.25 Error: unbound signature: ValSig [closing report] std_in:1.1 Compiler Bug: ModUtil.shiftStamps.newEnv - bad arg - Comments: obviously the code has bugs, but I thought you'd want to see the "compiler bug" anyway, since it may be triggered by the bugs in the program. Status: fixed in 0.65 ------------------------------------------------------------------------------- 272. generalizing user bound type variables Submitter: Elsa Date: 9/7/90 Version: 0.65 Problem: user bound variables are occurring in the final type of a function. Code: fun f(x) = let val y : 'a -> 'a = x in y y end; Transcript: <transcript of session illustrating problem> - fun f(x) = let val y : 'a -> 'a = x in y y end; val f = fn : ('aU -> 'aU) -> 'a -> 'a - f (fn x: 'a => x); std_in:2.1-2.16 Error: operator and operand don't agree (bound type var) operator domain: 'aU -> 'aU operand: 'aU -> 'aU in expression: f ((fn <pat> : 'aU => x)) Comments: Error should be detected when function f is defined, rather than when it is applied. Status: fixed in 0.70 ------------------------------------------------------------------------------- 273. generalizing weak variables inside fn abstractions Submitter: Dave MacQueen Date: 10/3/90 Version: 0.52 and earlier Problem: let-bound variables were being generalized with too strong a weak type. Transcript: - val x = fn y => let val f = ref in f end; val x = fn : 'a -> '3b -> '3b ref Comments: Second bound type variable should be '2b instead of '3b. Fix: Added abs field to POLYty constructor to remember abstraction level at point where type generalization took place. Status: fixed in 0.53 ------------------------------------------------------------------------------- 274. weakness lost with flex record pattern Submitter: Colin Meldrum <colin@harlqn.co.uk> Date: 3/19/90 Version: 0.66 Problem: flex record patterns can cause weakness to be dropped, resulting in whole in type system. Code: - val a = let val foo = ref nil in (fn x as {...} => foo:=[x] | (y,z) => (); foo) end > val a = ref [] : ('a * 'b) list ref Comment: This is very unsafe and can for example allow the definition of a 'cast' function... fun cast (x) = ((a := (x,0) :: (!a)); #1(hd (!a))); Status: fixed in 0.74 ------------------------------------------------------------------------------- 275. illegal token with structure named ? Submitter: Nick Rothwell Date: 3/16/90 Version: ? Transcript: - structure ? = struct val x = 3 end; [succeeds] - ?.x; [fails with "illegal token"] - let open ? in x end; [succeeds] Status: fixed by 0.66 ------------------------------------------------------------------------------- 276. overriding included value spec Submitter: Dave Berry (db@lfcs.ed.ac.uk) Date: 3/22/90 Version: 0.66 Severity: major Problem: If a value spec in an included signature is redefined in the including signature, the value identifier keeps the type from the included signature, but it is printed as the type from the including signature. Transcript: signature Foo1 = sig val foo: string end; signature Foo2 = sig include Foo1 val foo: bool end; structure Foo: Foo2 = struct val foo = true end; Error: value type in structure doesn't match signature spec name: foo spec: string actual: bool Comments: Note: Once I worked out what was going on I was actually grateful, because I hadn't realised that the names clashed. Perhaps it would be useful if implementations could warn about such cases? Status: fixed in 0.73 ------------------------------------------------------------------------------- 276. weak polymorphism Submitter: Dave Berry (db@lfcs.ed.ac.uk) Date: 3/22/90 Version: 0.44 Severity: major Problem: Code: <example code that reproduces the problem> System.Control.weakUnderscore := true; structure RV: (* The bug doesn't appear if the signature isn't included. *) sig val create: int -> '_a -> '_a ref list end = struct (* The bug doesn't appear if the first arguiment is omitted (the code here doesn't use it, just to keep the example small. *) fun create size init = [ref init] end; (* The bug doesn't appear if this function is curried. *) fun extend (newmax, v) = RV.create newmax v; Transcript: This is the output from the compiler: structure RV : sig val create : int -> '_a -> '_a ref list end nj-bug, line 17: Error: nongeneric weak type variable extend : int * '0S -> '0S ref list Status: fixed in 0.70 ------------------------------------------------------------------------------- 277. incorrect "inconsistent equality property" error Submitter: dbm Date: 3/16/90 Version: 0.66 Severity: major Problem: Code: bug277.sml signature S1 = sig type d end; functor F(X: S1) : sig datatype a = C of X.d end = struct datatype a = C of X.d val f = fn (x : a) => x end; Transcript: bug277.sml: 11.3-11.24 Error: inconsistent equality properties (2) Status: fixed in 0.73 ------------------------------------------------------------------------------- 278. local structure declaration at top level Submitter: R. M. O'Neill (cmp7130@sys.uea.ac.uk) Date: 3rd April 1990 Version: 0.44a System: Sun 3/50 & 3/160S SunOS 3.5 Severity: Minor (but, should be easy to fix and I would prefer it fixed) Problem: Using 'local ... in ... end' with structures does not work at the top level, but does work when wrapped in a 'struct ... end' construct Code: local structure Internal = struct val x=1 val y=2 end in structure First : sig val x : int end = Internal structure Second : sig val y : int end = Internal end [** As a TOP-LEVEL declaration **] Transcript: - local = structure Internal = struct val x=1 val y=2 end Error: expected IN, found STRUCTURE Error: expected END, found STRUCTURE = in Error: declaration or expression expected, found IN - structure First : sig val x : int end = Internal = structure Second : sig val y : int end = Internal Error: unbound structure name: Internal Error: unmatched val spec: x = end ; Error: unbound structure name: Internal Error: unmatched val spec: y Error: declaration or expression expected, found END - Compare-With: - structure Kludge = struct = local = structure Internal = struct val x=1 val y=2 end = in = structure First : sig val x : int end = Internal = structure Second : sig val y : int end = Internal = end = end ; structure Kludge : sig structure First : sig...end structure Second : sig...end end - Comments: Parser problem ? ( Expecting an 'ldec' rather than an 'sdec' ? ) [ I'm no SML internal workings guru !] Status: fixed by 0.66 ------------------------------------------------------------------------------- 279. big integers causing uncaught exception Submitter: John Reppy (jhr@cs.cornell.edu) Date: 4/4/90 Version: 0.55 System: ? Severity: major Problem: There seems to be a problem in the compiler with integers that are larger than 2^29-1. Transcript: Standard ML of New Jersey, Version 0.55, 1 April 1990 val it = () : unit - fun f (i : int, two_i : int) = ( = print i; print ": "; print two_i; print "\n"; f(i+1, two_i+two_i)); val f = fn : int * int -> 'a - f(0, 1); 0: 1 1: 2 2: 4 3: 8 ... 27: 134217728 28: 268435456 29: 536870912 uncaught exception - 536870912; uncaught exception - 536870911; val it = 536870911 : int Status: fixed in 0.66 on mipsb ------------------------------------------------------------------------------- 280. included infix specs not printed Submitter: John Reppy Date: 4/17/90 Version: 0.56 Severity: minor Problem: I noticed that if you include a signature that contains an infix specification, the infix specification doesn't get printed. Code: Transcript: - signature S1 = sig infix ## end; signature S1 = sig infix 0 ## end - signature S2 = sig include S1 end; signature S2 = sig end Status: fixed in 0.73 ------------------------------------------------------------------------------- 281. Import bombs out when it can't find files. Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: Tue Jul 17 11:01:09 BST 1990 Version: 0.59 System: Sun3, SunOS 4.1 Severity: You decide... Problem: Importing new files (ones which do not already have a '.bin' file) fails (with an uncaught exception) whilst attempting to import files which do not exist produces the same unfriendly message. Transcript: unix% ls file.sml unix% sml Standard ML of New Jersey, Version 0.59, 4 June 1990 - import "file"; uncaught exception SystemCall - import "nofile"; uncaught exception SystemCall - Perceived Reason: The timeFile function in sepcomp/importer.sml believes that the SysIO.mtime function will raise an Io exeption if it cannot find the file. In fact this exception is never returned by any of the routines in the SysIO module. When they encounter a problem they raise the SystemCall exception. Fix (currently untried): Option 1: Change the code for timeFile to trap the SystemCall exeption instead of the Io exception. e.g. <PATCH BEGIN> *** sepcomp/importer.sml.orig Fri Jun 1 14:08:02 1990 --- sepcomp/importer.sml Tue Jul 17 10:29:22 1990 *************** *** 159,165 **** in SOME sec end ! handle (Io _) => NONE fun createBinary(indent, filename, statModule: statModule, --- 159,165 ---- in SOME sec end ! handle (SystemCall _) => NONE fun createBinary(indent, filename, statModule: statModule, <PATCH END> Option 2: Create a new exception SysIO wich the module SysIO raises on failure and trap that. ( This is to my mind better since SystemCall is a rather wide exception to be trapping ). Status: fixed in 0.73 ------------------------------------------------------------------------------- 282. 'sharable' & 'pervshare' compilers produce different .bin Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: Mon Jul 23 10:53:45 BST 1990 Version: 0.60 System: Sun3/50, SunOS 4.1 Severity: You decide... Problem: Status: R The '.bin' files produced by the normal and the '-pervshare' versions of the compiler are different and each 'version' cannot load the other's '.bin' file reliably. Perhaps I have built the two versions differently, but I cannot see how since they were both built at the same time with the same .mo files (compiled with the 0.59 batch compiler). Below is a comprehensive transcript which should help in reproducing the bug, if it can be reproduced... Transcript: unix% cat > bug.sml functor test () = struct val it = "testing, testing, 1, 2, 3..." end unix% sml.pervshare Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "bug"; [reading bug.sml] [writing bug.bin... done] [closing bug.sml] functor test - ^D unix% sml.sharable Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "bug"; [reading bug.bin... done] [Major collection... 99% used (530424/535668), 1500 msec] [Increasing heap to 6920k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 11160k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 17520k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 22288k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 22656k] [Major collection... 100% used (530424/530424), 1420 msec] [Increasing heap to 22744k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 22752k] [Major collection... 100% used (530424/530424), 1400 msec] Warning: can't increase heap Ran out of memory unix% mv bug.bin bug.bin.sharable unix% sml.sharable Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "bug"; [reading bug.sml] [writing bug.bin... done] [closing bug.sml] functor test - ^D unix% sml.pervshare Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "bug"; [reading bug.bin... done] functor test - structure Test=test (); insttyc: NULLtyc Error: Compiler bug: Functor.applyFunctor.insttyc - ^D unix% mv bug.bin bug.bin.pervshare unix% cmp bug.bin.sharable bug.bin.pervshare bug.bin.sharable bug.bin.pervshare differ: char 62, line 2 unix% ll bug.bin.* -rw------- 1 cmp7130 1415 Jul 23 10:21 bug.bin.pervshare -rw------- 1 cmp7130 17331 Jul 23 10:18 bug.bin.sharable Status: Fixed (defunct feature) ------------------------------------------------------------------------------- 283. openread (run.c) checking Submitter: Peter Weinberger Date: 8/17/90 Version: ? Severity: minor Problem: openread() in run.c does not check to see if it runs off the end of its allowed space. Comments: in practice, this shouldn't be a problem, since openread() only reads the first two or three mo files, which should be smaller than the initial heap size. Status: fixed in 0.74 ------------------------------------------------------------------------------- 284. Poor type specification handling in mutually recursive functions. Submitter: Richard O'Neill (rmo%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: Tue Aug 14 10:04:21 BST 1990 Version: 0.64, 0.62, 0.56, ... System: Sun3/180, SunOS 4.1 Problem: When processing mutually recursive functions, Sml of NJ's current type mechanism prefers its own inferred types of functions to those specifically declared by the user. Code: type 'a foobar = {foo:'a, bar:'a} fun Foo (acc : 'a list foobar) (nil : 'a list) = acc | Foo {foo, bar} (h :: t) = Bar {foo=(h :: foo), bar=bar} t and Bar (acc : 'a list foobar) (nil : 'a list) = acc | Bar {foo, bar} (h :: t) = Foo {foo=foo, bar=(h :: bar)} t Transcript: unix% sml Standard ML of New Jersey, Version 0.64, 24 August 1990 val it = () : unit - use "code.sml"; [opening code.sml] type 'a foobar = {bar:'a,foo:'a} val Foo = fn : 'a list foobar -> 'a list -> 'a list foobar val Bar = fn : {bar:'a list,foo:'a list} -> 'a list -> 'a list foobar [closing code.sml] - - (* One would expect Foo & Bar to have the SAME type *) Comments: The type system seems to be deciding on the type of 'Bar' when it encounters it in the definition of 'Foo', and then sticking to that. Whilst it checks to see whether the type in the declaration of foo matches the type it has inferred, it does not change the 'Foo's type to be in line with its declaration. One can work around the problem by making sure that 'Bar' has the desired type the first time it is encountered. Thus, if Foo is defined as :- fun Foo (acc : 'a list foobar) (nil : 'a list) = acc | Foo {foo,bar} (h :: t) = Bar ({foo=(h :: foo), bar=bar} : 'a list foobar) t the correct types result :- type 'a foobar = {bar:'a,foo:'a} val Foo = fn : 'a list foobar -> 'a list -> 'a list foobar val Bar = fn : 'a list foobar -> 'a list -> 'a list foobar My (ancient) version of Poly/ML also exhibits the same behaviour. Status: not a bug; type abbreviations are not new types ------------------------------------------------------------------------------- 285. Bus error Submitter: Alain Deutsch, Laboratoire d'Informatique, LIX, Ecole Polytechnique, 91128 Palaiseau Cedex, France. Date: 8-30-1990 Version: Standard ML of New Jersey, Version 0.56, 13 April 1990 System: ULTRIX V4.0 (Rev. 174) System #1: Sat Feb 10 01:14:11 MET 1990 UWS V4.0 (Rev. 164) Severity: critical Problem: Bus error. Code: use "bug.sml"; (see enclosed files below, tarmail format) Transcript: Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - [opening /usr/users/lix/icsla/deutsch/ModeleSemantique/Bug/bug.sml] [opening Extensions.sml] type 'a printer = outstream * 'a -> unit type 'a transformer = 'a -> 'a [closing Extensions.sml] val it = () : unit [opening Utilities.sig.sml] signature Utilities = sig val assoc : ''a * (''a * 'b) list -> 'b option val butlast : 'a list -> 'a list val cartesian_product : 'a list * 'b list -> ('a * 'b) list val display_list : string * string * string * 'a printer -> 'a list printer val display_pair : string * string * string * 'a printer * 'b printer -> ('a * 'b) printer val error : string * string -> 'a val is_prefix : ''a list * ''a list -> bool val makestring_list : string * string * string * ('a -> string) -> 'a list -> string val member : ''a * ''a list -> bool val replace_prefix : (''a list * ''a list) * ''a list -> ''a list val update_alist : ''a * 'b * (''a * 'b) list -> (''a * 'b) list end [closing Utilities.sig.sml] val it = () : unit [opening Strings.sig.sml] signature Strings = sig type T val < : T * T -> bool val Display : T printer val Hash : T -> int val MakeString : T -> string val New : string -> T end [closing Strings.sig.sml] val it = () : unit [opening Aliases.sig.sml] signature Aliases = sig type Aliases type Path datatype Accessor con IntAcc : int -> Accessor con NamedAcc : string -> Accessor val ++ : Path * Accessor -> Path val Add : Path * Path -> Aliases transformer val Adds : Path list * Path list -> Aliases transformer val Aliased : Path * Path -> Aliases -> bool val Aliases : Path * Aliases -> Path list val DisplayAccessor : Accessor printer val DisplayPath : Path printer val MakeStringAcc : Accessor -> string val MakeStringPath : Path -> string val NewPath : Accessor list -> Path val PathDrop : Path * int -> Path val PathLength : Path -> int val PathNth : Path * int -> Accessor val Remove : Path list -> Aliases transformer val SetVariable : Path * Path -> Aliases transformer end [closing Aliases.sig.sml] val it = () : unit [opening Object.sig.sml] signature Object = sig type T val Display : T printer end [closing Object.sig.sml] val it = () : unit [opening OrderedSet.sig.sml] signature OrderedSet = sig type T val < : T * T -> bool val Display : T printer end [closing OrderedSet.sig.sml] val it = () : unit [opening Map.sml] Map.sml:125.6-127.68 Warning: match not exhaustive tree ((key,_),_,empty,_) => ... tree ((key,_),_,nonempty_subtree,_) => ... pid 4566 (sml) was killed on unaligned access, at pc 0x6016e0 Process SML bus error Comments: The files loaded in "use.sml" are indeed necessary to reproduce the bug. Removing any one of them suppresses that particular occurence of the bug, bug, but only shifts the problem. Fix: Perhaps the GC, as suggested by the vanishing nature of the bug. Enclosed files: see bug285.tarmail Status: probably fixed by 0.73 ------------------------------------------------------------------------------- 286. Compiler bug: inststr NULLstr Submitter: Bob Harper (Robert.Harper@cs.cmu.edu) Date: 9/6/90 Version: ? Severity: minor Problem: Compiler bug secondary error Code: functor AbsSyn( structure Id : ID and UnOp : UNOP and BinOp : BINOP ): ABSSYN = struct end; structure AbsSyn : ABSSYN = AbsSyn( structure Id = Id ); (* because I forgot to add in the extra parameters *) Transcript: The result on execution is: /tmp/sml.tmp.k01743:2.5-2.10 Error: unmatched structure spec: UnOp /tmp/sml.tmp.k01743:2.5-2.10 Error: unmatched structure spec: BinOp Error: Compiler bug: inststr NULLstr Status: fixed in 0.70 ------------------------------------------------------------------------------- 287. cosine function incorrectly defined Submitter: Valerio Pinci Date: SEPT 6, 1990 Version: 0.62 System: Sparc Station 1, SUN OS 0.43 Severity: major Problem: cos function returns wrong values. Code: cos 0.0; Transcript: - cos 0.0; val it = 0.0 : real Fix: In boot/math.sml, change "fun cos x = sin(PI-x)" to "fun cos x = sin(PIo2-x)". Status: fixed in 0.66 ------------------------------------------------------------------------------- 288. extraneous "match not exhaustive" warning Submitter: John (jhr@cs.cornell.edu) Date: 9/8/90 Version: 0.64 System: sun-4 Severity: minor Problem: extraneous "match not exhaustive" warning Code: Transcript: <transcript of session illustrating problem> Standard ML of New Jersey, Version 0.64, 24 August 1990 val it = () : unit - fun f 0 = 0 | f i = 1; std_in:1.5-1.21 Warning: match not exhaustive val f = fn : int -> int - fun f 0 = 0 | f _ = 1; std_in:3.5-3.21 Warning: match not exhaustive val f = fn : int -> int - f 5; val it = 1 : int Comments: [Appel] I tried this on version 0.64 on our dec 5810, and it works fine (no extraneous "match not exhaustive" messages). Was yours a profiling version or something like that? I tried it on a sun-4 here (version 0.64) and the bug did not show up, so it's not machine-specific. Status: fixed in 0.69 ------------------------------------------------------------------------------- 289. 0.65 prerelease core dumps Submitter: Bob Ballance (ballance@cascade.cs.unm.edu Date: 9/13/90 Version: 0.65 System: ? Severity: critical Problem: core dump Code: >>>>>>>>>> Sample file --- Causes failure of 0.65. Running "agcd" after failed load causes core dump.<<<<<<<<< (* * Stephen R. Wheat, 9/6/90 * CS550 - HW1 *) (* * Find the greatest common divisor *) fun gcd(1,b) = 1 (* avoid an endless situation *) | gcd(a,1) = 1 (* avoid an endless situation *) | gcd(0,b) = b (* most likely the one evenly divides the other *) | gcd(a,0) = a (* most likely the one evenly divides the other *) | gcd(a,b) = if (a<b) then gcd(a,b mod a) else (* if they are equal, the next recursion will get the answer *) gcd(a mod b,b); (* * My own absolute value function *) fun abs(a) = if (a<0) then ~a else a; (* * Find the gcd, regardless of the signs of the parameters *) fun agcd(a,b) = gcd(abs(a),abs(b)); (* * Convert a rational number (represented as a 2-tuple) into its reduced form *) fun reduce(a,b) = let val c = agcd(a,b) in if (c = 1) then (* this avoids an endless recursion *) (a,b) else reduce((a div c),(b div c)) end; Status: fixed in 0.69 ------------------------------------------------------------------------------- 290. bin files of share/noshare versions are incompatible Submitter: Eric Cooper (Eric.Cooper@cs.cmu.edu) Date: 9/18/90 Version: 0.65 System: ? Severity: minor Problem: The one problem I still have is that sml-noshare gets an illegal instruction when it tries to import a .bin file written by the sharable sml, and vice versa. Also, the .bin files produced by sml-noshare are much larger than those produced by sml. For example, compiling stream.sig.sml produces the following .bin files: -rw-r--r-- 1 ecc 2664 Sep 18 13:04 obj/stream.sig.bin -rw-r--r-- 1 ecc 14904 Sep 18 13:17 obj-noshare/stream.sig.bin Code: (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) (* STREAM: signature for a lazy stream.*) signature STREAM = sig type 'xa stream val streamify : (unit -> '_a) -> '_a stream val cons : '_a * '_a stream -> '_a stream val get : '_a stream -> '_a * '_a stream end Comments: same as 282 Status: Fixed (defunct feature) ------------------------------------------------------------------------------- 291. floating point on sparc Submitter: Bernard Sufrin Date: 9/18/90 Version: 0.56 System: Sparc Problem: The ``bad'' functions seem to compile incorrectly on Sparc machines but ok on 68020 machines. Looks like >=0.0 is compiled wrongly, but the circumstances are mystifying. Why does the presence of the pair parameter seem to be critical (offset calculation in the machine-specific code-generator?). Code: (* try ??bad(0.0, 0.0) (~0.2) *) fun bad (x, y) l = if l >= 0.0 then x else bad(x+l, y) (~l); fun alsobad (x, y) l = if l>0.0 orelse l=0.0 then x else alsobad(x+l, y) (~l); fun good (x, y) l = if 0.0 <= l then x else good(x+l, y) (~l); fun alsogood x y l = if l >= 0.0 then x else alsogood(x+l) y (~l); Status: fixed in 0.65 ------------------------------------------------------------------------------- 292. debugger and interpreter incompatible Submitter: Todd Knoblock Todd@eecs.umich.edu Date: 24 September 1990 Version: 0.65 System: Decstation 3100 under bsd AND Sun4/sparc under sunos Severity: Very Minor Problem: Compilation of sml with interpretor and debug packages fails Transcript: command: makeml -decstation bsd -i -debug or makeml -sun4 sunos -i -debug appears to progress normally until [closing dbguser/hio.sml] val it = () : unit [opening dbguser/hstore.sml] [opening debug/weak.sml] Error: Compiler bug: bad primop in interp [closing debug/weak.sml] [closing dbguser/hstore.sml] [closing dbguser/userlevel.sml] Comments: Running the compilation without the -i works on both platforms. If the interpretor and debugger are truly incompatible, then makeml should flag it. (apt) They aren't incompatible: the interpreter was broken. Status: fixed as of 0.88, but interpreter breaks elsewhere on debugger code. ------------------------------------------------------------------------------- 293. debug problems Submitter: Todd Knoblock, todd@eecs.umich.edu Date: 26 September 1990 Version: SML 0.65, emacs 18.55.1 System: Decstation under ultrix and Sun sparc under sunos Severity: error message: minor, no output: critical Synopsis: I am having two problems with the emacs debug package. The first is quite minor: on start-up on a non-x-display (like my terminal at home), emacs reports the following error when loading sml-init: file mode specification error: (void-variable-x-button-m-left). The second is more serious. When sending to the sml process, I do not get output until I move (c-x o/c-x b) into the process buffer. For example, if I have this in a buffer fun f(0) = 1 | f(x) = x*(f (x-1)); and type c-c c-c, then if sml has not been run before, emacs will bring up a window, and start it properly. However, the only output is Standard ML of New Jersey, Version 0.65, 10 September 1990 val it = () : unit - emacsInit (); cd "/afs/engin.umich.edu/user/t/o/todd/"; [opening /tmp/sml.tmp.a02351] Once I move into the buffer, then I get the rest of the output: val f = fn : int -> int [closing /tmp/sml.tmp.a02351] If sml is already running, and the window is not visible, then sending to the buffer does not cause it to become visible. Comments: If I disable the debugging code, by removing the two "hooks" in sml-init, then the interface works as in the past. I am running emacs version 18.55.1, and have tried it on two platforms: decstation under ultrix, and a sparc under sunos. Finally, it appears that the file outdent.el is redundant now, and could be removed from the distribution. Comments: [apt, 2/1/93] These bugs aren't fixed. The first is just a trivial error message. As to the second: we don't really guarantee that c-c c-c and similar emacs interface tricks will work with the debugger. You could "not a bug" these if you want, though they should get addressed eventually -- I deliberately didn't spend time on minor emacs-related problems last summer. Status: open ------------------------------------------------------------------------------- 294. weak polymorphic types Submitter: David Berry Date: 9/24/90 Version: 0.65 Severity: major Problem: The Memo structure in the Library still doesn't compile under SML-NJ 0.65 It compiles under Poly/ML, and is based on a version for Edinburgh ML. Transcript: - use "memo.sml"; [opening memo.sml] [opening ../signatures/Memo.sml] signature Memo = sig val memo : (Nat -> Nat) -> ('a -> Nat) -> (('a -> '_b) -> 'a -> '_b) -> ('a -> '_b) * ('a -> '_b) val memo2 : (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> (('a -> '_b -> '_ c) -> 'a -> '_b -> '_c) -> ('a -> '_b -> '_c) * ('a -> '_b -> '_c) val memo3 : (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> ('_c -> Nat) -> ( ('a -> '_b -> '_c -> '_d) -> 'a -> '_b -> '_c -> '_d) -> ('a -> '_b -> '_c -> '_ d) * ('a -> '_b -> '_c -> '_d) val version : real end [closing ../signatures/Memo.sml] val it = () : unit memo.sml:41.7-53.33 Error: nongeneric weak type variable memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU -> '~3Z) * ('aU -> '~3Z) memo.sml:41.7-53.33 Error: nongeneric weak type variable memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU -> '~3Z) * ('aU -> '~3Z) memo.sml:41.7-53.33 Error: nongeneric weak type variable memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU -> '~3Z) * ('aU -> '~3Z) memo.sml:41.7-53.33 Error: nongeneric weak type variable memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU -> '~3Z) * ('aU -> '~3Z) memo.sml:58.5-58.76 Error: operator and operand don't agree (circularity) operator domain: ('Z -> '~3Y) -> 'Z -> '~3Y operand: ('Z -> '~3Y) -> 'Z -> '~3X -> '~3Y in expression: memo expfn injy ((fn _ => (fn <rule>))) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec name: memo spec: (Nat -> Nat) -> ('a -> Nat) -> (('a -> '_b) -> 'a -> '_b) -> ('a -> '_ b) * ('a -> '_b) actual: (Nat -> Nat) -> ('a -> Nat) -> (('a -> '~3Z) -> 'a -> '~3Z) -> ('a -> '~3Z) * ('a -> '~3Z) memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec name: memo2 spec: (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> (('a -> '_b -> '_c) -> 'a -> '_b -> '_c) -> ('a -> '_b -> '_c) * ('a -> '_b -> '_c) actual: (Nat -> Nat) -> ('a -> Nat) -> ('~3Z -> Nat) -> (('a -> '~3Y) -> 'a -> '~3Z -> '~3Y) -> error memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec name: memo3 spec: (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> ('_c -> Nat) -> (('a -> '_b -> '_c -> '_d) -> 'a -> '_b -> '_c -> '_d) -> ('a -> '_b -> '_c -> '_d) * ( 'a -> '_b -> '_c -> '_d) actual: (Nat -> Nat) -> ('a -> Nat) -> ('b -> Nat) -> ('~3Z -> Nat) -> (('a -> '~3Y) -> 'a -> 'b -> '~3Z -> '~3Y) -> ('a -> '~3Y) * ('a -> '~3Y) [closing memo.sml] - Comment: for Memo.sml to compile, the name of structure Array in Bytearray.sml has to be changed. Status: fixed in 0.74 ------------------------------------------------------------------------------- 295. Compiler bug: r_o in mcopt Submitter: Kung Chen Date: 9/30/90 Version: 0.56 System: Sparc, Sun OS Problem: the optimization phase of pattern-mtaching dies Code: (* Categorical Abstract Machine simulator*) (* D. Rabin, 5-aug-90, translated to SML by K. Chen, 10-sept-90*) structure Cam = struct (* CAM instructions*) datatype 'val CAMinstr = QuoteInstr of 'val | PrimInstr of int * string | AccInstr of int | ConsInstr | CdrInstr | CarInstr | PushInstr | SwapInstr | BranchInstr of 'val CAMinstr list * 'val CAMinstr list | CurInstr of 'val CAMinstr list | AppInstr | ReturnInstr | UpdInstr | IdInstr type 'val Code = 'val CAMinstr list datatype 'const Val = Simple of 'const | Close of 'const Val * 'const Val CAMinstr list | Pair of 'const Val * 'const Val | Truth of bool | Save of 'const Val CAMinstr list (* CAM state*) datatype 'const CAMstate = CAMst of 'const Val * 'const Val list * (('const Val) CAMinstr) list | Halt (* CAM state transition function*) (* fun step : 'const CAMstate -> 'const CAMstate *) fun step CAMst(x, s, []) = Halt |step CAMst(x, s, IdInstr::is) = CAMst(x, s, is) |step CAMst(Pair(x, y), s, CarInstr::is) = CAMst(x ,s, is) |step CAMst(Pair(x, y), s, CdrInstr::is) = CAMst(y, s, is) |step CAMst(x, s , PushInstr::is) = CAMst(x, (x :: s), is) |step CAMst(x, (y :: s), SwapInstr::is) = CAMst(y ,(x :: s), is) |step CAMst(x, (y :: s), ConsInstr::is) = CAMst(Pair(x, y), (x :: s), is) |step CAMst(x, s, CurInstr(code)::is) = CAMst(Close(x, code), s ,is) |step CAMst(Pair(Close(x, code), y), s, AppInstr :: is) = CAMst(Pair(x, y), Save(is)::s, code) |step CAMst(x, Save(code)::s, ReturnInstr::is) = CAMst(x, s, code) |step CAMst(x, s, QuoteInstr(c)::is) = CAMst(c, s, is) |step CAMst(Pair(x,Truth(true)), s, BranchInstr(ifTrue, ifFalse)::is) = CAMst(x, s, ifTrue) |step CAMst(Pair(x, Truth(false)), s, BranchInstr(ifTrue, ifFalse)::is) = CAMst(x, s, ifFalse) |step CAMst(x, (y :: s), UpdInstr::is) = CAMst(y, s, is) end Transcript: - use "cam.sml"; [opening cam.sml] Error: Compiler bug: r_o in mcopt [closing cam.sml] Status: fixed in 0.69 ------------------------------------------------------------------------------- 296. patch for HP/MORE Submitter: Brian Boutel (brian@comp.vuw.ac.nz) Date: 11 Oct 90 Version: 0.66 System: m68020 (H-P workstation) more/bsd Severity: Problem: source error in src/runtime/ml_os.h. Will not compile. Code: n/a Transcript: n/a Comments: I reported this for 0.56, the first version in which my patches for more/bsd on H-P workstations were included. The line in the source has been changed, but only to include the same fix for NeXT machines. Fix: src/runtime/ml_os.h. Add the underlined code: /* where to find syscall.h, used for getting the #define SYS_open */ #if defined(VAX) || defined(NeXT) || defined(MORE) ~~~~~~~~~~~~~~~~ #include <syscall.h> #else #include <sys/syscall.h> #endif Status: fixed in 0.71 ------------------------------------------------------------------------------- 297. Bits.lshift on Sun4 Submitter: Eric Cooper <ecc@cs.cmu.edu> Date: 11 October 1990 Version: Standard ML of New Jersey, Version 0.66, 15 September 1990 System: Sun4, both SunOS and Mach Severity: minor Problem: 1. Calls to Bits.lshift with constant arguments that should raise Overflow cause a compiler error message instead. 2. With non-constant arguments, Bits.lshift expressions that should raise Overflow don't. Code: (1) Bits.lshift(1,30); (2) fun lshift (x, y) = Bits.lshift (x, y); lshift (1, 30); lshift (1000000, 64); Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - fun lshift (x, y) = Bits.lshift (x, y); val lshift = fn : int * int -> int - lshift (1, 30); val it = ~1073741824 : int (* should raise Overflow *) - lshift (1000000, 64); val it = 1000000 : int (* shifting by any multiple of 32 appears to be equivalent to shifting by 0; should raise Overflow *) - Bits.lshift (1, 30); Error: Compiler bug: [SparcCM.ashr] - (); SIGILL code 0x2 Comments: [Cooper] The number of bits to shift is evidently being reduced modulo 32. [jhr] The lshift operation does not raise Overflow (Andrew's decision). I'll look at the other problem. [jhr] When there is a compiler bug (at least in the backend), the state of the system gets screwed up in such a way that the system core dumps. Is it possible to do a better job of cleaning up when a compiler bug is detected? An example is (on 0.66/sparc) - Bits.lshift (1, 30); Error: Compiler bug: [SparcCM.ashr] - (); SIGILL code 0x2 [appel] I don't see where the Definition of Standard ML says that lshift should raise Overflow! Status: fixed in 0.66? ------------------------------------------------------------------------------- 298. tags inconsistency Submitter: Allen Leung allen@sbcs.sunysb.edu Date: 12 Oct 1990 Version: NJSML v0.66 System: sun4 Severity: very minor Problem: runtime tags of evaled and unevaled suspension has been reversed Comments: The runtime tags of evaluated and unevaluated suspension in System.Tags are inconsistent with the ones in tags.h Status: ok in 0.70 ------------------------------------------------------------------------------- 299. user-bound tyvars Submitter: John Reppy Date: Version: 0.66 Severity: major Problem: There are two versions of the first line of the sync function: one produces the error, the other works. Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use "compbug.sml"; [opening compbug.sml] compbug.sml:8.3-57.5 Error: value type in structure doesn't match signature spec name: sync spec: 'a event -> 'a actual: 'a event -> 'aU [closing compbug.sml] Code: compbug.sml signature INTERNAL_CML = sig type 'a event val sync : 'a event -> 'a end functor ConcurML () : INTERNAL_CML = struct exception Never and Escape exception Sync (* for signature compatability *) datatype evt_sts = EVT_ANY | EVT_READY | EVT_BLOCK type 'a base_evt = { pollfn : unit -> evt_sts, dofn : unit -> 'a, blockfn : bool ref -> 'a } datatype 'a event = EVT of 'a base_evt list local datatype 'a ready_evts = NO_EVTS (* no ready events *) | ANY_EVTS of (int * (unit -> 'a) list) (* list of ready anyevents *) | RDY_EVTS of (int * (unit -> 'a) list) (* list of ready events *) fun extract _ = NO_EVTS (* Generate index numbers for "non-deterministic" selection. We use a * round-robin style policy. *) val cnt = ref 0 fun random i = let val j = !cnt in cnt := j+1; (j mod i) end fun selectEvt (_, [f]) = f() | selectEvt (n, l) = (nth(l, random n)) () in (* sync : 'a event -> 'a *) fun sync (EVT []) = raise Never (** THIS DOESN'T WORK **) (* fun sync ((EVT []) : 'a event) = raise Never *) (** THIS WORKS **) | sync (EVT el) = ( case (extract el) of NO_EVTS => callcc (fn sync_k => let val evtflg = ref false fun log ({blockfn, ...} : 'a base_evt)= (throw sync_k (blockfn evtflg)) handle Escape => () in app log el; (*atomicDispatch()*) raise Sync end) | ANY_EVTS anyevts => selectEvt anyevts | RDY_EVTS evts => selectEvt evts) end (* local *) end (* functor ConcurML *) Status: not a bug? (check with MacQueen) ------------------------------------------------------------------------------- 300. uncaught exceptin RegBind Submitter: Soren Christensen, University of Aarhus, Computer Science Dep., Denmark schristensen@daimi.dk Date: 17 oct 90 Version: 0.65 System: Sun4/280 / SunOS 4.0.1 Severity: Critical Problem: Code: (* filename: nb *) datatype ''a ms = !! of ( (int * ''a) * (''a ms) ) | empty; fun cr (0,_) = empty | cr (coef,col) = (!!((coef,col),empty)); fun foo (c:int ms ref) = true andalso (1 = length [1]) andalso (cr (1,1) = (!c)) andalso (empty = (!c)); Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use "nb"; [opening nb] datatype 'a ms con !! : (int * 'a) * 'a ms -> 'a ms con empty : 'a ms val cr = fn : int * 'a -> 'a ms [closing nb] uncaught exception Regbind - val x = 5; Illegal instruction Status: fixed in 0.69 ------------------------------------------------------------------------------- 301. Compiler bug: tycPath Submitter: Andrew Appel Date: 10/24/90 Version: 0.66 Severity: minor Problem: The following program gets Error: Compiler bug: tycPath after all the syntax errors. Perhaps it should be a CASCADE. Code: struct VMat : sig type v4 = real*real*real*real type m4 = v4*v4*v4*v4 val vmul = v4*v4 -> v4 val vdot = v4*v4 -> real val vmmul = v4*m4 -> v4 val mmul = m4*m4 -> m4 end = struct fun vmul((v1x, v1y, v1z, v1w), (v2x, v2y, v2z, v2w)) = (v1x * v2x, v1y * v2y, v1z * v2z, v1w * v2w) fun vdot((v1x, v1y, v1z, v1w), (v2x, v2y, v2z, v2w)) = v1x * v2x + v1y * v2y + v1z * v2z + v1w * v2w fun vmmul(v, (a, b, c, d)) = (vdot(v, a), vdot(v, b), vdot(v, c), vdot(v, d)) fun mmul((a, b, c, d), m) = (vmmul(a, m), vmmul(b, m), vmmul(c, m), vmmul(d, m)) end Status: fixed in 0.71 ------------------------------------------------------------------------------- 302. match not exhaustive warnings from import have wrong location Submitter: Peter Canning <canning@hplabs.hp.com> Date: 24 October 1990 Version: 0.66 System: 68020 HP-UX 7.0 Severity: major Problem: match not exhaustive warnings from import have wrong location Code: functor foo() = struct datatype T = I of int | B of bool | S of string fun foo(I i) = i | foo(B b) = if b then 1 else 0 end; Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - import "foo"; [reading foo.sml] foo.sml:0.0-0.0 Warning: match not exhaustive I i => ... B b => ... [writing foo.bin... done] [closing foo.sml] functor foo Comments: The warning message should give line.column different from 0.0-0.0 Status: Fixed (defunct feature) ------------------------------------------------------------------------------- 303. bad error reporting Submitter: Nick Date: 25 Oct 90 Version: 0.66 System: irrelevant Severity: minor Problem: junk error reporting Code: foobar + 3; Transcript: (OK:) Comments:std_in:1.1-1.6 Error: unbound variable foobar (bogus:)std_in:1.1-1.10 Error: operator and operand don't agree (type mismatch) operator domain: undef * undef operand: undef * int in expression: + (foobar,3) (bogus:)std_in:1.8 Error: overloaded variable "+" not defined at type: undef Status: fixed in 0.73 ------------------------------------------------------------------------------- 304. SIGEMT on sparc Submitter: Nick Rothwell Date: 10/25/90 Version: 0.66 System: sparc Severity: major Problem: 0.66 has a SIGEMT problem on SPARC's, on hitting ^C (sometimes). Will try and narrow down if I can. Also from Mike Crawley <mjc@abstract-hardware-ltd.co.uk>, in 0.73: I have been able to repeat the following bug a number of times. Pressing ^C to interrupt sml while it is busy can sometimes crash it. The saved image I was using was 10MB at the time. ^C SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0x9dd8) Mike Crawley. Abstract Hardware Ltd. Status: fixed in 0.73 ------------------------------------------------------------------------------- 305. Strange floating point error Submitter: tmb@ai.mit.edu (Thomas M. Breuel) Date: 11/28/90 Version: 0.66 System: Sun4/SunOS4.1 Problem: division by zero causes "strange floating point error" Code: 0.0/0.0 Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 0.0/0.0; strange floating point error Process Inferior sml exited abnormally with code 3 Comments: Other division-by-zero errors for floating point numbers raise Div. Status: fixed in 0.69 ------------------------------------------------------------------------------- 306. list printing, printlength Submitter: tmb@ai.mit.edu Date: 10/28/90 Version: SML of NJ 0.66 System: Sun 4/SunOS 4.0 Severity: minor Problem: extraneous "dots" printed Code: [1,2,3,4,5,6,7,8,9,10,11,12]; Transcript: - [1,2,3,4,5,6,7,8,9,10,11,12,13]; val it = [1,2,3,4,5,6,7,8,9,10,11,12,...] : int list - [1,2,3,4,5,6,7,8,9,10,11,12]; val it = [1,2,3,4,5,6,7,8,9,10,11,12,...] : int list - Comments: Since there are no unprinted elements in the 12 element list, there should be no ellipsis either. Status: fixed in 0.74 ---------------------------------------------------------------------------- 307. signature matching in 0.69 Submitter: Greg Morrisett jgmorris@cs.cmu.edu Date: April 29, 1991 Version: 0.67 and 0.69 System: DECstation 3100, Mach and Sun-3 Mach Severity: critical? Problem: nested structures and signature matching Code: signature SIG1 = sig structure T : sig type t end structure U : sig structure V : sig val s : T.t end end end structure S : SIG1 = struct structure T = struct datatype t = FOO end structure U = struct structure V = struct val s = T.FOO end end end Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "bug.sml"; [opening bug.sml] $$ lookTycPath 1: 0 0 tyconInContext: [0,0] [closing bug.sml] uncaught exception Subscript - Comments: I reduced this down to as small a problem as I could. For instance, removing any of the enclosing structures makes the bug go away. This works under version 0.64 and 0.65. This came up in some "real" code and there is no easy work-around... Fix: ??? Status: fixed in 0.73 --------------------------------------------------------------------------- 308. Mips RC6280 code generation bug Submitter: Toshinori Maeno <tmaeno@cc.titech.ac.jp> Computer Center, Tokyo Institute of Technology Date: 1991-06-01 Version: 0.66 <SML of NJ version number> System: MIPS RC6280, 128MB; Riscos 4.52 Severity: critical (at least for us :-) Problem: makeml dumps core after successful make of runtime/run Code: makeml -mips riscos Transcript: makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.mipsb mo makeml> (cd runtime; rm -f run allmo.o allmo.s) makeml> (cd runtime; make MACHINE=MIPS 'CFL= -systype bsd43' 'DEFS= -DRISCos -DRUNTIME=\"runtime\"' linkdata) cc -g -signed -systype bsd43 -DMIPS -DRISCos -DRUNTIME=\"runtime\" -o linkdata linkdata.c makeml> runtime/linkdata [runtime/IntMipsBig.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o makeml> (cd runtime; make MACHINE=MIPS 'DEFS= -DRISCos' 'CPP=/lib/cpp -P' 'CFL= -systype bsd43' 'AS=as') cc -g -signed -systype bsd43 -DMIPS -DRISCos -c run.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c run_ml.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c callgc.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c gc.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c MIPS.dep.c /lib/cpp -P -DASM -DMIPS -DRISCos MIPS.prim.s > prim.s as -o prim.o prim.s cc -g -signed -systype bsd43 -DMIPS -DRISCos -c export.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c timers.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c ml_objects.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c cfuns.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c cstruct.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c signal.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c exncode.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c malloc.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -o run run.o run_ml.o callgc.o gc.o MIPS.dep.o prim.o export.o timers.o ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o allmo.o makeml> echo ( exportML "sml"; output(std_out,System.version); output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 4096 -r 20 -h 2048 IntMipsBig [Increasing heap to 2049k] [Loading mo/CoreFunc.mo] [Executing mo/CoreFunc.mo] [Loading mo/Math.mo] [Executing mo/Math.mo] [Loading mo/Initial.mo] [Executing mo/Initial.mo] makeml: 18680 Illegal instruction - core dumped ^ This number may be different for another run. Comments: On MIPS RC3240, makeml successfully made sml. runtime/run made on RC6280 works on RC3240 without problem. runtime/run made on either system dumps core on RC6280. 0.68 reproduced the same problem. I disabled FlushIcache, but could not get improvement. I shall report this to MIPS, too. [jgm] I assume this is the problem of using the branch delay slots for some non-standard reason? Status: Fixed in 0.70; other RC6280 problems not quite fixed in 0.71. --------------------------------------------------------------------------- 309: NeXTstation exported image doesn't work Submitter: oneill@cs.sfu.ca Date: 28 Mar 91 Version: 0.68 System: NeXTstation Severity: Problem: boots and exports, but exported image bombs with SEGV when invoked Fix: Heres the changes I made to get as far as I got, (note, TRAP #2 on a NeXT flushes the 68040 code cache, which is necessary after a gc). Richard, (used to be {cmp7130,rmo}@sys.uea.ac.uk) my diffs (w.r.t 0.68)... diff -r -c runtime.orig/callgc.c runtime/callgc.c *** runtime.orig/callgc.c Wed Mar 6 11:50:57 1991 --- runtime/callgc.c Thu Mar 21 15:19:19 1991 *************** *** 86,95 **** --- 86,103 ---- int live_size = old_high - arenabase; int a = 0; ML_val_t x = gcmessages; + #ifdef NeXT + extern void * get_edata(); + #else extern int edata; + #endif resettimers(); + #ifdef NeXT + lastbreak = (int)get_edata(); + #else lastbreak = (int)&edata; + #endif gcmessages = INT_CtoML(0); new_size = compute_new_size(live_size); do { *************** *** 330,335 **** --- 338,346 ---- arend = arenabase+arenasize; arstart = (((arend+old_high)/2)+3)&(~3); (*arptr) = arstart; + #ifdef NeXT + asm("trap #2"); + #endif } /* end of callgc */ diff -r -c runtime.orig/export.c runtime/export.c *** runtime.orig/export.c Wed Nov 21 11:34:06 1990 --- runtime/export.c Thu Mar 21 15:08:53 1991 *************** *** 87,93 **** --- 87,97 ---- * > set a_entry as address of start procedure */ + #ifdef NeXT + extern void * get_etext(); + #else extern int etext; /* &etext is just beyond the end of the text segment */ + #endif extern int old_high; static int textstart,datastart; *************** *** 425,432 **** int datasize, bsssize; E.magic = MH_MAGIC; ! E.cputype = CPU_TYPE_MC68030; ! E.cpusubtype = CPU_SUBTYPE_NeXT; E.filetype = MH_EXECUTE; E.ncmds = 3; E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn) --- 429,436 ---- int datasize, bsssize; E.magic = MH_MAGIC; ! E.cputype = CPU_TYPE_MC680x0; ! E.cpusubtype = CPU_SUBTYPE_MC68040; E.filetype = MH_EXECUTE; E.ncmds = 3; E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn) *************** *** 442,448 **** tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn); strcpy(tcmd.segname,SEG_TEXT); tcmd.vmaddr = textstart; ! tcmd.vmsize = (int) CEIL(((int)&etext),getpagesize())-textstart; tcmd.fileoff = 0; tcmd.filesize = tcmd.vmsize; tcmd.maxprot = VM_PROT_ALL; --- 446,452 ---- tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn); strcpy(tcmd.segname,SEG_TEXT); tcmd.vmaddr = textstart; ! tcmd.vmsize = (int) CEIL(((int)get_etext()),getpagesize())-textstart; tcmd.fileoff = 0; tcmd.filesize = tcmd.vmsize; tcmd.maxprot = VM_PROT_ALL; >From cs.cornell.edu!jhr Fri Mar 29 10:46:22 0500 1991 Received: by coma; Fri Mar 29 10:46:27 EST 1991 Received: by inet.att.com; Fri Mar 29 10:46 EST 1991 Received: from MAUI.CS.CORNELL.EDU by cloyd.cs.cornell.edu (5.65/I-1.98N) id AA21402; Fri, 29 Mar 91 10:46:22 -0500 Date: Fri, 29 Mar 91 10:46:22 -0500 From: jhr@cs.cornell.edu (John Reppy) Message-Id: <9103291546.AA27105@maui.cs.cornell.edu> Received: by maui.cs.cornell.edu (5.65/N-0.12) id AA27105; Fri, 29 Mar 91 10:46:20 -0500 To: appel@princeton.edu, dbm@research.att.com Subject: Re: NeXT 68040 attempt Status: R I have integrated Richard O'Neill's changes into my 0.68, in a style that is more consistant with the runtime system. Here are the diffs; maybe they can be included in 0.69. (BTW, there are probably still some other changes needed to make this work). - John <jhr@maui:97> diff -c ml_os.h ml_os.h.ORIG *** ml_os.h Fri Mar 29 10:40:07 1991 --- ml_os.h.ORIG Wed Nov 21 14:34:31 1990 *************** *** 111,122 **** (syscall(SYS_sysmips, MIPS_CACHEFLUSH, (addr), (size), ICACHE, 0)) # endif #else ! #ifdef NeXT ! # define FlushICache(addr, size) asm ("trap #2") ! #else ! # define FlushICache(addr, size) #endif - #endif #if defined(MACH) && defined(MIPS) --- 111,118 ---- (syscall(SYS_sysmips, MIPS_CACHEFLUSH, (addr), (size), ICACHE, 0)) # endif #else ! #define FlushICache(addr, size) #endif #if defined(MACH) && defined(MIPS) *************** *** 158,163 **** --- 154,160 ---- #define READDIR(fd,buf,sz) getdirentries((fd), (buf), (sz), &dummy) #endif + #if defined(BSD) || defined(RISCos) || defined(HPUX) || defined(SGI) #define HAS_WRITEV #include <sys/uio.h> *************** *** 164,175 **** #define HAS_NONBLOCKING_IO #endif ! #ifdef NeXT ! extern void *get_edata(); ! # define EDATA ((int)get_edata()) ! #else ! extern int edata; ! # define EDATA ((int)(&edata)) ! #endif #endif !_ML_OS_ --- 161,167 ---- #define HAS_NONBLOCKING_IO #endif ! ! #endif !_ML_OS_ <jhr@maui:98> diff -c callgc.c callgc.c.ORIG *** callgc.c Fri Mar 29 10:41:06 1991 --- callgc.c.ORIG Wed Mar 6 14:50:57 1991 *************** *** 86,94 **** int live_size = old_high - arenabase; int a = 0; ML_val_t x = gcmessages; resettimers(); ! lastbreak = EDATA; gcmessages = INT_CtoML(0); new_size = compute_new_size(live_size); do { --- 86,95 ---- int live_size = old_high - arenabase; int a = 0; ML_val_t x = gcmessages; + extern int edata; resettimers(); ! lastbreak = (int)&edata; gcmessages = INT_CtoML(0); new_size = compute_new_size(live_size); do { >From cs.sfu.ca!oneill Wed Apr 24 18:22:39 EDT 1991 Received: by coma; Wed Apr 24 18:22:39 EDT 1991 Received: by inet.att.com; Wed Apr 24 18:22 EDT 1991 Received: by relay.CDNnet.CA (4.1/1.14) id AA23566; Wed, 24 Apr 91 15:20:58 PDT From: <oneill@cs.sfu.ca> Date: 24 Apr 91 15:13 -0700 To: dbm@research.att.com Cc: jhr@cs.cornell.edu Message-Id: <9104242213.AA15593@phoenix.cs.sfu.ca> Subject: Re: Getting Sml up and running on a NeXT running OS2.[01] Status: R Long long ago, you (dbm) wrote: > I think we should have SML of NJ running on the 68040 NeXTs soon, > since John Reppy has just bought one of them (to write his thesis > on). He is confident he can get SML running on it quite quickly. > I'll forward your message to him, since it looks like a useful start > on the problem. John Reppy also wrote: > It may be a while before I can fix this, since I still need to get a decent > sized disk. Well, after a month of messing about with other things, I finally got arround to getting sml working the NeXT (my NeXT arrived and so I could work on it at home). I'll tell you the problem and give my diffs. The problem was that, among the various load commands needed in the executable's header, one is needed to load the c shared library, and this was ommited (since previously programs weren't *forced* into using the shared libraries). Since the load command is always exactly the same, I did a ghastly hack and substituted the thing in as a constant (array stuffed with the right hex numbers). This isn't quite the cleanest thing to do, but I was only concerned with getting it to work for me. (Yeah, I know, I'm lazy...) Anyway, diffs follow, and it at least it works now... Richard, ---8<--cut-here--(and ruin your monitor)--cut-here--8<--- *** export.c.orig Wed Nov 21 11:34:06 1990 --- export.c Wed Apr 10 17:06:57 1991 *************** *** 87,93 **** --- 87,98 ---- * > set a_entry as address of start procedure */ + #ifndef NeXT extern int etext; /* &etext is just beyond the end of the text segment */ + #else + extern void *get_etext(); + #endif + extern int old_high; static int textstart,datastart; *************** *** 422,436 **** static unsigned long thcount; static struct NeXT_thread_state_regs ntregs; static unsigned int hdrsize; int datasize, bsssize; E.magic = MH_MAGIC; ! E.cputype = CPU_TYPE_MC68030; ! E.cpusubtype = CPU_SUBTYPE_NeXT; E.filetype = MH_EXECUTE; ! E.ncmds = 3; E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn) ! + sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn) + sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs); E.flags = MH_NOUNDEFS; --- 427,445 ---- static unsigned long thcount; static struct NeXT_thread_state_regs ntregs; static unsigned int hdrsize; + static unsigned int lcmd[] = {0x00000006, 0x00000030, 0x00000014, 0x0000002c, + 0x05000000, 0x2f757372, 0x2f73686c, 0x69622f6c, + 0x69627379, 0x735f732e, 0x422e7368, 0x6c696200}; + int datasize, bsssize; E.magic = MH_MAGIC; ! E.cputype = CPU_TYPE_MC680x0; ! E.cpusubtype = CPU_SUBTYPE_MC68040; E.filetype = MH_EXECUTE; ! E.ncmds = 4; E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn) ! + sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn) + sizeof(lcmd) + sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs); E.flags = MH_NOUNDEFS; *************** *** 442,448 **** tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn); strcpy(tcmd.segname,SEG_TEXT); tcmd.vmaddr = textstart; ! tcmd.vmsize = (int) CEIL(((int)&etext),getpagesize())-textstart; tcmd.fileoff = 0; tcmd.filesize = tcmd.vmsize; tcmd.maxprot = VM_PROT_ALL; --- 451,457 ---- tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn); strcpy(tcmd.segname,SEG_TEXT); tcmd.vmaddr = textstart; ! tcmd.vmsize = (int) CEIL(((int)get_etext()),getpagesize())-textstart; tcmd.fileoff = 0; tcmd.filesize = tcmd.vmsize; tcmd.maxprot = VM_PROT_ALL; *************** *** 515,520 **** --- 524,530 ---- bulletproofWrite(filid,&dcmd,sizeof(dcmd)); bulletproofWrite(filid,&dsectn,sizeof(dsectn)); bulletproofWrite(filid,&bsectn,sizeof(bsectn)); + bulletproofWrite(filid,&lcmd,sizeof(lcmd)); bulletproofWrite(filid,&uthr,sizeof(uthr)); bulletproofWrite(filid,&thflavor,sizeof(thflavor)); bulletproofWrite(filid,&thcount,sizeof(thcount)); >From cs.cornell.edu!jhr Wed Apr 24 20:41:38 0400 1991 Received: by coma; Wed Apr 24 20:42:39 EDT 1991 Received: by inet.att.com; Wed Apr 24 20:42 EDT 1991 Received: from MAUI.CS.CORNELL.EDU by cloyd.cs.cornell.edu (5.65/I-1.98N) id AA00996; Wed, 24 Apr 91 20:41:38 -0400 Date: Wed, 24 Apr 91 20:41:38 -0400 From: jhr@cs.cornell.edu (John Reppy) Message-Id: <9104250041.AA16310@maui.cs.cornell.edu> Received: by maui.cs.cornell.edu (5.65/N-0.12) id AA16310; Wed, 24 Apr 91 20:41:37 -0400 To: dbm@research.att.com, oneill@cs.sfu.ca Subject: Re: Getting Sml up and running on a NeXT running OS2.[01] Cc: appel@cs.cornell.edu, jhr@cs.cornell.edu Status: R > From oneill@cs.sfu.ca Wed Apr 24 18:22:04 1991 > > Long long ago, you (dbm) wrote: > > I think we should have SML of NJ running on the 68040 NeXTs soon, > > since John Reppy has just bought one of them (to write his thesis > > on). He is confident he can get SML running on it quite quickly. > > I'll forward your message to him, since it looks like a useful start > > on the problem. > > John Reppy also wrote: > > It may be a while before I can fix this, since I still need to get a decent > > sized disk. > > Well, after a month of messing about with other things, I finally got arround > to getting sml working the NeXT (my NeXT arrived and so I could work on it at > home). I'll tell you the problem and give my diffs. > > ... Thanks for the fix. I'll merge these diffs into 0.69, and it should part of 0.70 (whenever that is). - John [jgm] Rumor has it that jhr has 0.69 running on the NeXTstation? Status: Fixed? --------------------------------------------------------------------------- 310. HP Cache flush problem Submitter: Nick Rothwell Date: 23 May 1991 Version: 0.66 System: HP9000/380 (a /300 with go-faster 68040 option) Severity: Critical for this system; fairly major overall Problem: Bombs with random bus errors or other traps on 68040-based HP machines. The build sequence runs, but not much else. Maybe it's a problem with saved images or something Code: <almost anything> Transcript: (i) Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 3; EMT instruction (core dumped) (ii) Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 3; Segmentation fault (core dumped) (iii) Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 3; val it = 3 : int (iv) Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 3; exnCode: code was 0 Fix: From: Andy Norman <ange@hplb.hpl.hp.com> A solution to your problem is to change the caching to 'writethrough' instead of 'copyback' on the data region of the dumped sml image. i.e. chatr -Cd sml This is documented in the file /etc/newconfig/ReleaseNotes and on the man page for chatr. Hope this helps... a bit... -- ange -- ange@hpl.hp.co.uk From: Andrew Appel <appel@Princeton.EDU> Message-Id: <9105240134.AA10277@cs.Princeton.EDU> To: ange.hpl.hp.co.uk@cs.Princeton.EDU Cc: dbm@inet.att.com I'm intrigued by your mail about write-through. Perhaps we can still use write-back, if we flush the cache whenever the garbage collector (etc.) moves code around. There is a provision in the runtime system to do this for machines like the MIPS where the i-cache does not track updates to the data. Could this be the problem? (grep for FLUSH in the runtime) Status: Fixed? --------------------------------------------------------------------------- 311. abstype bug Submitter: Russ Green (rjg@lfcs) Date: Version: System: Severity: minor Problem: doesn't compile the following abstype definition Code: abstype t = C1 | C2 with fun f (x:t,y:t) = x=y end [jgm] This is fixed under 0.69. Fix: Status: Fixed --------------------------------------------------------------------------- 312. non-printable characters cause exception Abort to be raised Submitter: John Reppy (jhr@cs.cornell.edu) Date: Wed Feb 6 1991 Version: 0.69 Severity: minor Problem: I've noticed that if you type a non-printable character (such as a control character), then you get an uncaught exception Abort. Code: Transcript: - ^W std_in:1.1 Error: illegal token uncaught exception Abort Comment: in parse/parse.sml, the first token is extracted from the input stream in order to initialize the parse. Unfortunately, this is outside the scope of the appropriate exception handler. Status: Fixed in 0.84 --------------------------------------------------------------------------- 313. poor error message Submitter: John Reppy (jhr@cs.cornell.edu) Date: Thu, 20 Jun 91 Version: 0.69 System: Severity: minor Problem: I tripped across a poor error message last night. Assume we have a 7 line file "xxx.sml" with the following contents: (* 1 *) fun foo () = let (* 2 *) fun bar () = let (* 3 *) val z = 1 (* 4 *) in (* 5 *) z (* 6 *) end (* 7 *) val w = 1 The error being that we forgot the body of foo's let. The error message that SML/NJ gives is: Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "xxx.sml"; [opening xxx.sml] xxx.sml:7.19 Error: syntax error found at EOF [closing xxx.sml] - Comments: When foo is in the middle of a 1000 line file, figuring out the source of the error becomes quite hard. If the error message had the line range, it would be a lot better. Fix: perhaps allow specification in mlyacc that a three-token insertion should be tried; in this case "in 0 end" Same approach could fix bug 206. Status: open --------------------------------------------------------------------------- 314. unbalanced brackets on error message Submitter: John Reppy (jhr@cs.cornell.edu) Date: Mar 5 1991 Version: 0.66-0.69 Severity: minor Problem: Minor bug in 0.66: if you use a non-existent file, the resulting diagnostic has unbalanced brackets: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use "nonexistent"; [use failed: open_in "nonexistent": open failed, No such file or directory Status: fixed in 0.74 --------------------------------------------------------------------------- 315. bad weakness degree (too weak) Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/15/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: bad weakness degree (too weak); Code: Transcript: - fun f g x = g x; val f = fn : ('a -> 'b) -> 'a -> 'b - f ref; std_in:2.1-2.5 Error: nongeneric weak type variable it : '0Z -> '0Z ref std_in:2.1-2.5 Error: nongeneric weak type variable it : '0Z -> '0Z ref - Comments: f ref should have type: '1a -> '1a ref (DBM: but can't tell this without examining the definition of f) Status: not a bug ------------------------------------------------------------------------- 316. stronger than required equality-type inference Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/15/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: stronger than required equality-type inference Code: Transcript: - datatype 'a new = N of 'a ref; datatype 'a new con N : 'a ref -> 'a new - fun f (X as ref x) (Y as ref y) = N X = N Y; val f = fn : ''a ref -> ''a ref -> bool - Comments: Not really a bug, but confusing. I may understand the reason why, but type of f above is unnecessarily strong; type 'a ref -> 'a ref -> bool would be enough as equality property for type constructor "new" does not depend upon its type argument (due to the ref in "N of 'a ref"). It is surprising that references to functions would admit equality, while constructions from these by N (as built in function f) would not. e.g. - let val r = ref (fn x=>x) in r=r end; val it = true : bool - let val r = ref (fn x=>x) in N r = N r end; std_in:3.1-3.47 Error: operator and operand don't agree (equality type required) operator domain: ''Z * ''Z operand: ('0Y -> '0Y) new * ('0Y -> '0Y) new in expression: = (N r,N r) - - datatype 'a new0 = N0; - fun g x = x=N0; val g = fn : ''a new0 -> bool - Comments: g should have type: 'a new0 -> bool (DBM: see TACS paper) Status: not a bug ------------------------------------------------------------------------- 317. eqtypes and abstype Submitter: Simon Finn (simon@abstract-hardware-ltd.co.uk) Date: Sep 20, 1990 Version: 0.69 Severity: Problem: shouldn't allow since the datatype constructor "Y" doesn't respect equality in the final environment (since it maps the non-equality type "abs" to the equality type "repp"). Poly/ML [and SML/NJ] fail to detect this. Code: abstype abs = X of int with datatype rep = Y of abs; val foo = X 1 end; fun eq x y = Y x = Y y; eq foo foo; Transcript: type abs con Y : abs -> rep val foo = - : abs val eq = fn : abs -> abs -> bool val it = true : bool Status: open --------------------------------------------------------------------------- 318. rebinding of type operator "*" Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: One is allowed to rebind type operator "*", but the new "*" is not properly handled in types, and old product type operator still present. Code: Transcript: - datatype * = P; datatype * con P : * - P; val it = P : * - fun f (x : *) = P; std_in:5.12 Error: syntax error found at ASTERISK - fun f (x : 'a * 'b) = (1,2); val f = fn : 'a * 'b -> int * int Comments: Is it really safe to allow rebinding of product type ? This operator must be parsed as special case anyway, as product type operator does not obey the same syntax as user definable type operators. Further, function type operator may not be rebound. [jgm] see Dave Tarditi's comments -- (x: *) is a syntax error since *) is a close comment delimiter. Fix: Status: fixed ------------------------------------------------------------------------------ 319. bad weakness degree (not weak enough) Submitter: Thierry Le Sergent (lesergen@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: major Problem: bad weakness degree (not weak enough); may create toplevel polymorphic references; Code: Transcript: - fun f x = let fun g z = ref x in g 3 end; val f = fn : '2a -> '2a ref - f []; val it = ref [] : '1a list ref Comments: f above should have type '1a -> '1a ref; Fix: propagate weakness for free as well as bound type variables (function instantiateType in basics/typesutil.sml). Status: fixed in 0.72 ------------------------------------------------------------------------------ 320. bad weakness degree (too weak) Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: bad weakness degree (too weak); Code: Transcript: - fun f x = (ref x; fn x=>x) x; std_in:1.5-1.28 Error: nongeneric weak type variable f : '0Z -> '0Z std_in:1.5-1.28 Error: nongeneric weak type variable f : '0Z -> '0Z - fun g x y = (ref x; fn x=>x) x; val g = fn : '1a -> 'b -> '1a Comments: f above should have type '1a -> '1a g above should have type '2a -> 'b -> '2a some rator forms confuse the type checker; which generate higher weakness degrees than expected. Fix: added base field to type absp in typing/typecheck.sml (but see bug 539). Status: fixed in 0.67 ------------------------------------------------------------------------------ 321. top level polymorphic exceptions allowed Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: top level polymorphic exceptions allowed Transcript: - exception X of '0a; exception X - fun f x = raise X x; val f = fn : '0aU -> 'a - fun g h x = h x handle X y => y; val g = fn : ('a -> '0aU) -> 'a -> '0aU Comments: This would be a bug if I could raise that exception, but I could not; so ? As a comment, I would prefer the compiler to infer automatically weakness degrees for arguments of polymorphic exceptions, rather than asking the user to (sometime unconsistently) apply a type constraint. Weakness degrees are neglected in types appearing in, e.g., datatype declarations; I think this is a good practice, that I would generalize to all types written by the user. Status: fixed in 0.74 ------------------------------------------------------------------------------ 322. unreachable constructors should not be printed Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: unreachable constructors should not be printed Code: Transcript: - fun f x = let exception X of '1a in raise X x end; val f = fn : '1a -> 'b - f 5; uncaught exception X - fun f x = let datatype new = N in N end; val f = fn : 'a -> ?.new - f 1; val it = N : ?.new Comments: Not a bug, but confusing, as X and N above are not reachable at toplevel; and some reachable values may be printed as these. Fix: Status: not a bug, but confusing ------------------------------------------------------------------------------ 323. blast_read/write should have types Submitter: Jawahar (malhotra%metasoft.uucp@BBN.COM) Date: Wed, 8 May 91 Version: 0.69 Severity: minor Problem: I'm trying to use blast_read/write to dump some functors into a file in binary form and then reload them in another image. I tried a small experiment and found that it causes a segmentation fault. Is there something I'm doing wrong? I used: - val x = {a=34,b=78}; - System.Unsafe.blast_write (x, "x.bl"); and - System.Unsafe.blast_write ("x.bl", x); both of them failed. Code: (see above) Transcript: Comments: [jgm] The first argument of blast_write and the argument of blast_read should be of type outstream and instream respectively. In system.sig, they're given types 'outstream * 'a -> unit and 'instream -> 'a making them polymorphic. I'm sure there's a reason for this, but I don't know what it is. Status: fixed in 0.84 --------------------------------------------------------------------------- 324. bulletproofWrite dies in a bad way when out of disk space Submitter: Larryf Paulson (Larry.Paulson@computer-lab.cambridge.ac.uk) Date: 27 Nov 90 Version: System: Severity: minor Problem: when out of disk space, an exportML dies in an ugly way. Code: Transcript: A New Jersey execution failed giving the following message. Do you know what it means? Out of memory perhaps? Larry [Major collection... 99% used (1915968/1921456), 4860 msec] bulletproofWrite, errno = 28 *** Error code 3 Comments: The bulletproofWrite error you got was probably from an exportML, no? It's not out of memory; you have no space left on your disk. However, we should provide a better error message, of course. Status: fixed in 0.71 --------------------------------------------------------------------------- 325. import and symlinks Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: Mon Apr 8 15:52:46 MET DST 1991 Version: Standard ML of New Jersey, Version 0.65, 10 September 1990 System: Sun3-260 / SunOS Release 4.0.3_Export Sun4-370 / SunOS Release 4.1.1 Problem: if the source file is a symbolik link import checks the modification time of the link but not of the file. Fix: *** cfuns.c.new Tue Apr 9 12:11:46 1991 --- cfuns.c.org Wed Aug 22 15:28:17 1990 *************** *** 715,721 **** int sts; if (OBJ_isBOXED(f)) ! sts = stat((char *)PTR_MLtoC(f), buf); else sts = fstat(INT_MLtoC(f), buf); --- 715,721 ---- int sts; if (OBJ_isBOXED(f)) ! sts = lstat((char *)PTR_MLtoC(f), buf); else sts = fstat(INT_MLtoC(f), buf); Comments: I use symbolik-links to share the source-code but not the bin-files for architectures sun3 and sun4 Status: Fixed (defunct feature) ------------------------------------------------------------------------- 326. very big arrays Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: Tue Apr 9 12:40:24 MET DST 1991 Version: Standard ML of New Jersey, Version 0.65, 10 September 1990 System: Sun3-260 / SunOS Release 4.0.3_Export Sun4-370 / SunOS Release 4.1.1 Problem: creating very big arrays leads to the message: [Minor collection...bug: insufficient to_space Comments: [jgm] I tried fairly large arrays under 0.69 (10,000,000 integers) and everything worked fine. Fix: don't know Status: Fixed ------------------------------------------------------------------------- 327. large constants cause overflow in compilation Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: Tue Apr 23 13:50:05 MET DST 1991 Version: Standard ML of New Jersey, Version 0.69, 3 April 1991 System: Sun4-370 / SunOS Release 4.1.1 Problem: Big integer constants leads to an uncaught exception Overflow in codegen. Script: Script started on Tue Apr 23 13:39:20 1991 jubu@flp jubu/ml_bugs 1) smlp69 Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - val x = 1024 * 1024 * 512; val x = 536870912 : int - val maxint = x + ( x - 1 ); val maxint = 1073741823 : int - System.Control.debugging := true; execution val it = () : unit - 1073741823; parse semantics debug instrument translate convert cpsopt closure globalfix spill codegen uncaught exception Overflow - 1; parse semantics debug instrument translate convert cpsopt closure globalfix spill codegen done about to boot code size =300 codegen uncaught exception Overflow - 1; parse semantics debug instrument translate convert cpsopt closure globalfix spill codegen done about to boot code size =188 codegen execution val it = 1 : int - jubu@flp jubu/ml_bugs 2) script done on Tue Apr 23 13:41:24 1991 Fix: Status: Fixed as of version 0.69 --------------------------------------------------------------------------- 328. callcc not tail recursive Submitter: John Reppy (jhr@cs.cornell.edu) Date: Jan 14 1991 Version: System: Severity: minor Problem: callcc is not tail-recursive Code: Transcript: Comments: Fix: To make callcc tail-recursive, replace the "callcc" conversion code of cps/convert.sml (starting at line 201) with the following: of Lambda.APP(Lambda.PRIM P.callcc, f) => let val h = mkLvar() and k = mkLvar() and x = mkLvar() val k' = mkLvar() and x' = mkLvar() in (* k is the callcc return cont, k' is the argument cont. *) FIX([(k, [x], c (VAR x))], PRIMOP(P.gethdlr, [], [h], [FIX( [(k', [x'], PRIMOP(P.sethdlr, [VAR h], [], [APP(VAR k, [VAR x'])]))], conv (f, fn vf => APP(vf, [VAR k', VAR k])))])) end Status: Fixed --------------------------------------------------------------------------- 329. checkopen broken Submitter: John Reppy (jhr@cs.cornell.edu) Date: Dec 6 1990 Version: 0.67 System: Severity: major Problem: Compiling Dave Berry's library produces a compiler bug in 0.67 Error: Compiler bug: EnvAccess.checkopen.test Code: Transcript: Standard ML of New Jersey, Version 0.67, 21 November 1990 val it = () : unit - use "nj-sml.load"; [opening nj-sml.load] ... [closing nj-sml.load] val it = () : unit - use "build.sml"; [opening build.sml] ... [closing ../signatures/InStreamType.sml] val it = () : unit structure Types : sig eqtype InStream end open Types Error: Compiler bug: EnvAccess.checkopen.test structure Types : sig end [opening outStream.sml] ... Comments: >From Lal George: The bug seems simple; checkopen.test was complaining if anything other than vals, exceptions, or structures were defined within a structure! The problem was only visible if this other thing (e.g., a type declaration) came before test had a chance to raise NotStale on something else. A revised version of test is as follows: Fix: let fun test (s:symbol) = case Env.look newenv s of VARbind(VALvar{access=PATH(v'::_),...}) => if v' = v then raise NotStale else () | CONbind(DATACON{rep=VARIABLE(PATH(v'::_)),...}) => if v' = v then raise NotStale else () | STRbind(STRvar{access=PATH(v'::_),...}) => if v' = v then raise NotStale else () | _ => () Status: Fixed -- however, the fix in 0.69 adds another arm to the case after the CONbind: | CONbind(DATACON{rep=VARIABLEc(PATH(v'::_)),...}) => if v' = v then raise NotStale else () --------------------------------------------------------------------------- 330. comments bug Submitter: David Tarditi (dtarditi@cs.cmu.edu) Date: 17 May 1991 Version: 0.69 System: Severity: minor Problem: According to Appendix D of the Commentary on Standard ML, an unmatched right comment bracket should be detected by the compiler. Thus the expression (op *) is illegal. Version 0.69 does not detect unmatched right comment brackets, and parses (op *). Code: (op *)(1,2); Transcript: - (op *)(1,2); val it = 2 : int Comments: Fix: add the following line to the lexer: <INITIAL>"*)" => (err(yypos,yypos+1) COMPLAIN "unmatched close comment"; continue()); Status: fixed in 0.71 --------------------------------------------------------------------------- 331. type variable generalized wrongly Submitter: Mike Fourman (mikef@lfcs.edinburgh.ac.uk) Date: Apr 16 1991 Version: System: Severity: major? Problem: The following is not legal ML and is rejected by PolyML, Poplog ML and the Edinburgh Kit compiler. NJ-ML and the old Edinburgh ML (wrongly) accept it. fn x => let val y : 'a -> 'a = fn z => x in y end; Error message from the Kit compiler (the others are more obscure): The following type variables could not be bound, even though they are scoped at this declaration. 'a Code: fn x => let val y : 'a -> 'a = fn z => x in y end; Transcript: Comments: Comment from David Turner: Once the new parser has been properly integrated, the above error will also show the declaration where the type variable was scoped (as below). fn x => let val y : 'a -> 'a = fn z => x in y end; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following type variables could not be bound, even though they are scoped at this declaration. 'a Fix: Status: Fixed as of 0.69 --------------------------------------------------------------------------- 332. Allows null datatype constructor to be matched as a unit -> type function. Submitter: stark@cs.sunysb.edu (Gene Stark) Date: 1/26/91 Version: 0.66 and 0.69 System: SparcStation SLC, SunOS 4.0.3c Severity: major Problem: Fails to type-check datatype constructors in functor body against specifications in signature. Mismatched types result in core dump when constructor is used incorrectly. Code: The compiler allows the following code: signature SIG = sig type value; val NIL: unit -> value end functor Foo(): SIG = struct datatype value = NIL end; After importing this code, executing the following causes a bus error: structure Str = Foo(); open Str; NIL(); Status: fixed in 0.73 --------------------------------------------------------------------------- 333. code generation bug Submitter: David Turner <dnt@uk.ac.ed.lfcs> Date: 31/10/90 Version: SML of NJ version 0.66 System: Mips, Sun3, Sun4, HP9000 Severity: ? Problem: Code generation problem causing ml to crash ? Code: (* This code has been distilled to narrow down the error! *) fun sine x = (if 1 mod 4 = 0 then exp(x) else exp(real 1 * x)) / sine x Transcript: uncaught exception Regbind (* Doesn't matter too much what you type here, the whole system seems to have been corrupted. *) - sin; Illegal instruction Comments: This happen on all the machines mentioned above (nearly always via an illegal instruction). This is clearly a problem with the new CPS stuff, but I'd like to again point out the other problem: code generation bugs, such as this one or the shift bug on the sparc, cause the system to get into some kind of corrupted state, which causes a core dump on the next top-level definition. I think that there needs to be a catch-all exception handler wrapped around code generation stuff, which will restore things to a reasonable state. - John The problem with System.Unsafe.Weak is that John forgot to make it an abstraction rather than a Structure. If this is fixed, haven no longer dumps core; I would hope shamash wouldn't get wedged either, though I don't intend to try the experiment! Andrew Trying to reproduce a bug that occurs on haven in 67, I typed open System.Unsafe.Weak; strong 1; This should give a typechecking error, but on haven, it causes a Bus Error. It looks like on shamash it wedges the machine! I'm investigating further on other machines. Status: Fixed as of 0.69 --------------------------------------------------------------------------- 334. adjust_limit in M68.prim.s Submitter: Andre Kramer akramer@ecrc.de Date: May 2 Version: 0.66 System: m68 (sun3 sunos) Severity: major? Problem: adjust_limit in M68.prim.s trashes d0 with a comment that ml does not use it. It appears that ML does use d0 (e.g. floating point primitives in same file). Code: I had an alarm signal handler causing random crashes. Transcript: . Comments: Sparc is ok. Fix: adjust_limit: movw cc,d5 /* save condition codes */ movl _saved_pc,sp@- movw d5,sp@- /* push the saved condition codes */ clrl d5 /* generate a trap on the next limit check */ rtr /* return, restoring condition codes */ Status: Fixed in 0.74. --------------------------------------------------------------------------- 335. Dave Berry's library won't compile Submitter: Richard O'Neill (oneill@cs.sfu.ca) Date: Wed Apr 24 09:57:05 PDT 1991 Version: 0.68-0.69 System: NeXTstation, OS2.1 Severity: Major Problem: The current 'working' version cannot compile Dave Berry's library (as in dblibrary.tar.Z in dist/ml on research.att.com). It chuggs away for a while but finally comes up with a Runbind exception. I can't say if it works for previous releases as 0.69 is the first version that runs on a NeXT under OS2.1, and thus the first release I have been able to run in a while. Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "nj-sml.load"; . . . - use "build_all.sml"; [opening build_all.sml] val loadEntry = fn : string -> unit val loadSig = fn : string -> unit val loadLocalSig = fn : string -> unit val setLoadPrefix = fn : string -> unit val setLoadSigPrefix = fn : string -> unit ... [opening Int.sml] [opening ../signatures/INT.sml] signature INT = sig eqtype T eqtype int ... val ~ : int -> int end [closing ../signatures/INT.sml] val it = () : unit [Major collection... 36% used (948744/2627428), 814 msec] [closing Int.sml] [closing build_all.sml] uncaught exception Runbind - Status: fixed in 0.74 --------------------------------------------------------------------------- 336. $$lookTycPath diagnostic message Submitter: Andre Appel (appel@princeton.edu) Date: Jun 3 1991 Version: 0.69 System: Severity: minor? Problem: Reminder: for 0.70 SML/NJ remove the $$lookTycPath diagnostic message. Fix: Status: fixed in 0.73 --------------------------------------------------------------------------- 337. double error message Submitter: John Ophel jlophel@watmsg.waterloo.edu Date: 4/1/91 Version: 0.66 System: Vax, Unix Severity: very minor Problem: repeated error message Transcript: - val g = (fn x => (fn y => (ref x, ref(x,y)))); val g = fn : '2a -> '2b -> '2a ref * ('2a * '2b) ref - val h = g(nil); val h = fn : '1a -> '1b list ref * ('1b list * '1a) ref - h true; std_in:4.1-4.6 Error: nongeneric weak type variable it : '0Z list ref * ('0Z list * bool) ref std_in:4.1-4.6 Error: nongeneric weak type variable it : '0Z list ref * ('0Z list * bool) ref Comments: I tried to generate the double error message with a simpler code but couldn't. John Status: fixed in 0.74 --------------------------------------------------------------------------- 338. local datatypes Submitter: Bruce Duba (duba@rice.edu) Date: Nov 8 1990 Version: System: Severity: major Problem: Is the following a bug or am I confused? I didn't expect the application of f1 to a2 to type check. Code: fun new() = let datatype A = A in (A,fn A => ()) end val (a1,f1) = new() val (a2,f2) = new() val x = f1 a2 Status: not a bug --------------------------------------------------------------------------- 339. type = allowed Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk) Date: Nov 8 1990 Version: System: Severity: minor Problem: SML/NJ allows the following code Code: signature S = sig type = end; Transcript: Comments: Here, "=" is clearly not standing for the equality predicate (even though it's not being rebound), so this is illegal. The status of something like signature S = sig structure T: sig ... end sharing type T.t = T.* end; is less clear. "*" is not allowed as a TyCon, but "T.*" presumably is (even though no matching signature for "T" would be syntactically possible to write). Sender: David.Tarditi@b.gp.cs.cmu.edu Status: RO Here are some answers to the questions about parsing in SML/NJ raised by Nick Rothwell. First, the processing of infix operators is handled by an operator precedence parser after parsing is finished. The ML-Yacc grammar essentially allows allow any string of legal identifiers in certain places; the operator precedence parser sorts it out later. (As a side note, this make syntactic error correction much harder). Yes, this means that we don't have a "pure" LALR grammar, but I don't see any way anyone could have one with the precedence scheme used in ML. The parser deals with "=" and "*" by always regarding them as reserved words. To put it another way, the lexer always returns separate tokens for these values. This reduces our problem to deciding where exactly "=" and "*" should be permitted to be used in place of identifiers. The following rules sort this out: "*" can always be used in place of an identifier, except in the syntactic class "TyCon" "=" can only be used in place of an identifier in an expression. Since it cannot be rebound, it cannot be used as an identifier in pattern. As Nick Rothwell has pointed out, there are some mistakes in SML/NJ where these rules are violated. To summarize the problems found so far: (1) Allows * to be used as TyCon in type specifications. This is clearly illegal SML (see p. 13 of the Definition). Example: sig type * end (2) Allows = to be used as TyCon in type specifications. Since this isn't the equality predicate, this is wrong. Example: sig type = end (3) Doesn't allow "*" to be used as a record label. This is clearly allowed, since "*" is just an identifier. Example {* = 5} All of these can be fixed by some minor changes to the grammar using by SML/NJ, without making the grammar ambiguous. With regard to parsing examples: (1) This is complicated, but not ambiguous. val x = {A=B=C=D=E, B=((X=Y), {X=Y}, X=Y), X=Y}; binds x to a record with fields A,B, and X. Field A is set to the boolean value of ((B=C)=D)=E), Field B is a tuple of type bool * {X:bool} * bool, and Field X is set to the value of Y. Thus: val B=1 and C=1 and D=true and E=true and X=1 and Y=1 val x = {A=B=C=D=E,B=((X=Y), {X=Y}, X=Y), X=Y} gives: val x = {A=true,B=(true,{X=1},true),X=1) : {A:bool,B : bool * {X : int} * bool, X : int} (2) This is legal; the Definition says nothing about rebinding the precedence of =. It won't typecheck though, since function types are not equality types. nonfix = val x = = and y = {A= =(=, =), B = =} (3) This should be illegal, but isn't. It shows that SML is inherently ambiguous for any fixed lookahead k. nonfix = fun f x = = | f y = case y of 1 => = | 2 => = | f z = = The reason is best illustrated with this simpler case fun f x = case y of 1 => 1 | f z = 3 The "| f z = 3" phrase should go with "fun f x", not with the case statement clause. A parser cannot decide this, however, until it sees that the "=" is not an "=>". However, z can be an arbitrarily complex pattern, so for fixed lookahead k we can choose some pattern that requires lookahead of k+1 tokens. There isn't much you can do about this, short of changing the language definition. The following variant is legal, by the way: nonfix = fun f x = = |00 stlouis8913372 "" \r\d in:--in: nuucp word: nuucpNUUCP to the problem of infixes in signatures making separate parsing and typehcecking passes difficult, it is already impossible (I think) to separate the parsing and typechecking completely. The infix status of an identifier cannot be determined without the use of static semantics information. You could separate the passes as: (1) parsing (2) typechecking plus parsing of infix identifiers if you insist on this kind of division. Dave Fix: Status: Fixed as of 0.69 --------------------------------------------------------------------------- 340. = specification allowed Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk) Date: 8 Nov 1990 Severity: minor Problem: The following (legal - I think) signature is accepted by SML/NJ and rejected by Poly/ML and Poplog/ML: Code: signature S = sig val = : 'a * 'a -> bool end also signature S = sig val = : int end Transcript: Comments: Is this legal? "val =" is only allowed if the "=" is standing for the equality predicate (Defn. p.4). Does its appearance in a spec. count? What about sig val = : int end where it can't possibly be the equality predicate. Status: not much of a bug --------------------------------------------------------------------------- 341. equality Submitter: Andrew Tolmach (apt@princeton.edu) Date: 4/17/91 Version: 0.68 Severity: major Problem: not consistent about allowing equality Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - datatype 'a A = A of 'a ref; datatype 'a A con A : 'a ref -> 'a A - val f = fn () => (); val f = fn : unit -> unit - val f1 = fn () => (); val f1 = fn : unit -> unit - f = f1; std_in:5.1-5.6 Error: operator and operand don't agree (equality type required) operator domain: ''Z * ''Z operand: (unit -> unit) * (unit -> unit) in expression: Initial.General.Initial.= (f,f1) - ref f = ref f1; val it = false : bool - ref 2 = ref 2; val it = false : bool - A (ref f) = A (ref f1); std_in:3.1-3.22 Error: operator and operand don't agree (equality type required) operator domain: ''Z * ''Z operand: (unit -> unit) A * (unit -> unit) A in expression: Initial.General.Initial.= (A (<exp> <exp>),A (<exp> <exp>)) - A (ref 2) = A (ref 2); val it = false : bool - Comments: If I can compare ref f with ref f1, why can't I compare A(ref f) with A(ref f1)? Is this a bug or a feature? Also, from Chet Murthy: I want to define a datatype, with constructors/destructors, for which the system can be forced to not provide an equality. I do not think this is possible. Here is the application: The Nuprl term-type is one for which constructors/destructors are crucial. But the term-type is defined in such a way that alpha-equal variants are not represented identically. So lambda(x.x) and lambda(y.y) are not the same structure. So structural equality will fail on them. So we define alpha-equality, which respects this equivalence. But the problem is that we do not want to discard structural equality completely. That is, if we were to add a new disjunct to the Nuprl term-type: datatype Term = .......... | Bogus of int -> int then Term would not be an eq-type, and structural equality would be inadmissible. But sometimes I DO want structural equality, like in hash-consing (and I'm not sure where else, but I don't want to rule that out). So I don't want to give it up right now. So it would be nice to define a structure which exported a datatype for the term-type, an equality function which happened to be defined as structural equality, but in which the term-type was NOT an eqtype. Is this possible? Here is my try - and the problem: signature ASIG = sig type t datatype DNE = D of int | Bogus of t val op == : DNE * DNE -> bool infix 4 == end; abstraction A:ASIG = struct type t = int datatype DNE = D of int | Bogus of t fun == (a,b) = (a = b) end; If I run (A.D 5)=(A.D 6) the system will happily run it. But I want the system to complain about DNE not being an eq-type. This isn't possible, is it? Status: not a bug (language problem, see Gunter,Gunter,MacQueen) --------------------------------------------------------------------------- 342. execute destroys the unix-environment Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: Fri Dec 21 16:12:49 MET 1990 Version: Standard ML of New Jersey, Version 0.66, 15 September 1990 System: Sun 4/60, 16Mbytes, SunOS Release 4.1 Problem: The function execute destroys the unix-environment Transcript: Script started on Fri Dec 21 16:07:27 1990 jubu@flp ml66/src 1) ./sml Standard ML of New Jersey, Version 0.66, 15 September 1990 - val (istr,ostr) = execute "/bin/sh"; - outputc ostr "echo '>'$DISPLAY'<'"; val it = () : unit - close_out ostr; val it = () : unit - inputc istr (can_input istr); val it = ">flp:0.0\220<\n" : string ^^^^ Comments: cfuns.c line 1100: The c-function exec has to add 0-bytes to the ml-strings. Fix: A simple fix can be done in perv.sml: perv.sml line 953: fun execute cmd = let fun add_0byte x = x^"\000\000 val (fdin, fdout) = exec (c_string cmd, [], List.map add_0byte(environ())) handle (SysError(_,msg)) => error("execute", cmd, msg) . . [jgm] Trying this on the SGI produces the following: Uncaught exception Io with "output "<std_out>": write failed, Broken pipe" Status: fixed in 0.74 (JHR) --------------------------------------------------------------------------- 343. Submitter: Ryan Stansifer ryan@cs.purdue.edu Date: May 11, 1991 Version: 0.66 Severity: minor Problem: wrong error message in non-gen exc bindings Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - exception e; exception e - val e' = e - exception e'' = e; exception e'' = e - raise e''; uncaught exception e - e'; val it = exn : exn - e''; val it = exn : exn - exception f = e'; std_in:3.15-3.16 Error: unbound exn: e' - exception f = e''; exception f = e'' Status: not a bug; perhaps the error message could be improved to indicate that e' is just a value, not a constructor --------------------------------------------------------------------------- 344. explicit type variable problem Submitter: Dave MacQueen (dbm@research.att.com) Date: Mar 30 1991 Version: through 0.74 Code: structure C : sig val f : 'a -> 'a end = struct exception E fun foo(k:'a option -> 'a) : 'a = k(NONE) fun bar(x:'a option) (y: 'a) = raise E fun f (e) = (* using (e:'a) as argument works *) foo (fn l => let fun g (x : 'a) = bar l x in g e end) end Comments: The rule for "scoping" explicit type variables like the 'a that appears in the definition of g is purely syntactic (i.e. doesn't take type checking, and its associated unifications, into account). Each explicit type variable is associated with with a particular val/fun declaration, and it should be generalized at that declaration, if possible. In this case 'a is associated with the "fun g" declaration, and we might annotate the definition of f accordingly: fun f (e) = (* using (e:'a) as argument works *) foo (fn l => let fun{'a} g (x : 'a) = bar l x in g e end) This means that the only legal place to generalize 'a would be at the definition of g. However, in this case the expression "bar l x" forces the type of l to be 'a option, meaning that 'a occurs in the type of the outer lambda bound variable l. This prevents the generalization of 'a at "fun g", so there is a conflict. Thus the program is not legal, but there should have been an error message about not being able to generalize 'a at "fun g", where it is syntactically scoped. I'll put in a fix to detect this situation and generate such an error message. Status: fixed in 0.85 --------------------------------------------------------------------------- 345. export should return a code and have different type Date: Nov 8, 1990 Severity: minor Problem: How come exportFn is string * (string list * string list -> unit) -> unit instead of string * (string list * string list -> int) -> 'a ? I was actually suggesting two things: the function passed as argument to exportFn should return an exit status and exportFn itself should "return" 'a rather than unit because it doesn't return. Of course, making exportFn's argument return exit status might break existing programs that use it; I don't know whether that's important or not at this stage of the game. If you want to write unix commands in ML, it's important to be able to set a return code. Comments: there is, of course, an "exit" function available for this purpose. Status: suggestion (not a bug) --------------------------------------------------------------------------- 346. exportFn Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: Mon Apr 8 15:52:46 MET DST 1991 Version: Standard ML of New Jersey, Version 0.66, 15 September 1990 System: Sun3-260 / SunOS Release 4.0.3_Export Sun4-370 / SunOS Release 4.1.1 Messages: Warning: can't increase heap Ran out of memory Comments: After an exportFn two pointers in Core.Refs are invalid. The addresses of (!Core.Refs.getDebugf) and (!Core.Refs.debugInterface) are bigger then (arenabase+arenasize) ! After an increase_heapsize the gc will collect some random-object. Bug Fix : change the type of Core.Refs.getDebugf and Core.Refs.debugInterface to (unit->unit) ref. (in file boot/core.sml) := will the do an boxed-update! Status: fixed in 0.84 --------------------------------------------------------------------------- 347. dec function in fastlib wrong Submitter: Andrew Appel (appel@princeton.edu) Date: Apr 15 1991 Version: 0.69 (and all previous) Severity: major Problem: In all versions up to and including 0.69, the "dec" function (decrement) in boot/fastlib.sml was wrong (it incremented). This will affect only those users who followed the hints for faster performance in the doc/ directory, which explained how to include Fastlib in one's programs. Unfortunately, I am such a user. What a waste of time. Status: fixed in 0.70 --------------------------------------------------------------------------- 348. connect_inet bug Submitter: John Reppy (jhr@cs.cornell.edu) Date: Mar 23 1991 Version: 0.68 Severity: minor Fix: If you haven't already built 0.69, then please include the following bug fix for connect_inet in runtime/cfuns.c: line 258, which is: saddr.sin_port = atoi(port); should be replaced with saddr.sin_port = htons(atoi(port)); and line 266, which is: saddr.sin_addr.s_addr = s; should be replaced with saddr.sin_addr.s_addr = htonl(s); Status: Fixed. --------------------------------------------------------------------------- 349. function names in FUN not checked for uniqueness Submitter: Andrzej Filinski <andrzej@cs.cmu.edu> Date: June 5, 1991 Version: 0.67 System: All Severity: Minor Problem: Function names in FUN not checked for uniqueness Code: fun foo x = 3 and foo x = true Transcript: - fun foo x = 3 and foo x = true; val foo = fn : 'a -> int val foo = fn : 'a -> bool - Comments: The equivalent VAL REC declaration is correctly rejected. Also, from Olof Johansson (olof@cs.umu.se) Is this a bug? What is the point of the definition? Is it allowed to do this according to the definition of SML? Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - datatype F = C and F = D; datatype F con C : F datatype F con D : F - D; > val it = D : F - C; > val it = D : F Which one of the following response is the correct one. Should they not be the same? Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - val rec f = fn x => 1 and f = fn y => 2; std_in:2.9-2.39 Error: duplicate function name in val rec dec: f - fun f x = 1 and f y = 2; val f = fn : 'a -> int val f = fn : 'a -> int - f 0; val it = 2 : int Olof Johansson Fix: Add checkUniq of function names to makeFUNdec in parse/corelang.sml or to FUNdec in absyn/absyn.sml Status: fixed in 0.71 --------------------------------------------------------------------------- 350. fvalbind rewrite rule Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk) Date: 12 Feb 1991 Version: System: Severity: minor Problem: Referring to the definition of the `fun' derived form (defn. V4 p68): there's a rewriting rule for fvalbind's looking like <op>var atpat.11 ... atpat.1n <: ty> = exp.1 <op>var atpat.21 ... atpat.2n <: ty> = exp.2 <op>var atpat.m1 ... atpat.mn <: ty> = exp.m <and fvalbind> This implicitly suggests that all the function result type constraints (whichever present) have to be the same. But, this is a *syntactic* constraint (we're dealing with derived forms, not elaboration rules). Certainly they have to elaborate to the same type, but surely they may be distinct syntactically? The above rule outlaws the following local type INT = int in fun f 0 : int = 0 | f 1 : INT = 1 end; Code: Transcript: Comments: Appel says: the Def'n should have subscripts on the ty's, and that's obviously what is meant here. Fix: Status: not a bug? --------------------------------------------------------------------------- 351. gc messages bug Submitter: Andrew Tolmach (apt@princeton.edu) Date: 7 May 1991 Version: 0.69 (and some earlier, 68 based versions) System: mipsb Severity: minor Problem: In version 69 (and some earlier, 68 based versions) on mipsb, the unsafe gc primitive interacts badly with gcmessages. Obviously this isn't a serious problem in itself, but maybe bears loking into...? Code: Transcript: - val gc = System.Unsafe.CInterface.gc; val gc = fn : int -> unit - (gc 0; gc 0); val it = () : unit - System.Control.Runtime.gcmessages := 3; val it = () : unit - (gc 0; gc 0); [Minor collection... 0% used (2224/765756), 10 msec] [Minor collection...bogus signal in ML: (5, 0x7) Comments: Fix: Status: should be fixed in 0.70 --------------------------------------------------------------------------- 352. gc statistics bug Submitter: Greg Morrisett (jgmorris@cs.cmu.edu) Date: June 25, 1991 Version: 0.69 System: All Severity: minor Problem: In callgc.c, there's a couple of places where you're trying to bump an ML_val_t int ref (e.g. majorcollections, collected, etc.) and using code like this: minorcollections += 2; But since ML_val_t is an unsigned int pointer, this bumps the value by 4 (i.e. ML 2). The safe way to add to an ML_val_t is to use INT_incr. Code: Transcript: Comments: Fix: change line 217 of callgc.c to read minorcollections = INT_incr(minorcollections,1); change lines 292-294 of callgc.c to read collected = INT_incr(collected, ((a+512)/1024)); collectedfrom = INT_incr(collectedfom, ((b+512)/1024)); majorcollections = INT_incr(majorcollections,1); Status: should be fixed in 0.70 --------------------------------------------------------------------------- 353. getWD can't get above mount points on NeXT Submitter: John Reppy (jhr@cs.cornell.edu) Date: Jun 7 1991 Version: 0.69 System: NeXT Severity: minor Problem: System.Directory.getWD doesn't seem to be able to get above mount points on the NeXT (works on the sun). E.g., Code: Transcript: <jhr@alvis:57> pwd /usr/fsys/loki/b/jhr <jhr@alvis:58> sml Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - System.Directory.cd ".."; val it = () : unit - System.Directory.getWD(); val it = "/" : string - System.Directory.cd ".."; val it = () : unit - System.Directory.getWD(); val it = "/usr/fsys/loki" : string Comment: See also 421. To be fixed by calling C version of getWD (after new gc allows malloc). Status: open --------------------------------------------------------------------------- 354. SIGILL bug on SPARC Submitter: John Reppy (jhr@cs.cornell.edu) Date: June 18 1991 Version: 0.69 System: SPARC Severity: major Problem: One of our alpha testers encountered a strange Overflow exception in eXene. Upon closer examination it turns out that the problem really is an illegal instruction exception (SIGILL), and that modifications made to support MACH on the SPARC caused SIGILL to be mapped to Overflow. Further examination demonstrates that the bug is neither an eXene bug or CML bug, but is a bug in SML/NJ. After a lot of testing I've managed to produce a small (<100 lines) example program, which will cause the bug on both the SPARC and DECstation 3100. The fact that this program uses the timer interrupts to do thread switching is key; if you turn the signals off, then the bug does not appear. I also note that the bug does not seem to appear in my version of 0.68 (0.67 + my changes for the unsafe callcc); thus I suspect that it was introduced by the changes made for supporting FP registers. The example program is included below; to produce the bug, run the function "go." It usually takes about 3-5 minutes to fail on a SPARCstation-1. For example, the following run took 2.5 min: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "sml-bug.sml"; [opening sml-bug.sml] val yield = fn : unit -> unit val spawn = fn : string * (unit -> unit) -> unit val doit = fn : (unit -> unit) -> unit val go = fn : unit -> unit [closing sml-bug.sml] val it = () : unit - go(); initial process proc1 proc2 proc1: uncaught exception Overflow initial process: uncaught exception Overflow val it = () : unit Code: (see John's CML code) Status: Fixed in 0.70 --------------------------------------------------------------------------- 355. incorrect line numbers with import Submitter: deutsch@poly.polytechnique.fr. Alain Deutsch, Laboratoire d'Informatique de l'Ecole Polytechnique (LIX) 91128 Palaiseau Cedex France. Date: Thu Nov 22 14:35:09 MET 1990 Version: Version 0.66 System: SUN3/60 Severity: minor Problem: Incorrect line/column numbers when compiling a module w. import, although the numbers are correct when compiling with use. Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use "ExampleFunctor.sml"; [opening ExampleFunctor.sml] ExampleFunctor.sml:3.9-3.18 Warning: match not exhaustive x :: nil => ... functor F : <sig> [closing ExampleFunctor.sml] val it = () : unit - import "ExampleFunctor"; [reading ExampleFunctor.sml] ExampleFunctor.sml:0.0-0.0 Warning: match not exhaustive x :: nil => ... [writing ExampleFunctor.bin... done] [closing ExampleFunctor.sml] functor F - Status: Fixed (Defunct feature) --------------------------------------------------------------------------- 356. size of images generated by import too large Submitter: Jawahar Malhotra (malhotra%metasoft@bbn.com) Date: Jan 29, 1991 Version: System: Severity: Problem: I recently redesigned a large system so that I could use separate compilation. I experienced an increase in heap size of close to 100%. This was a little disturbing and so I investigated a little. To explain the problem consider the following example: Say my system consists of 4 modules: A, B, C, D. Every functor is in a separate file as is every signature. To link, I execute 'use "link.sml"'. ++++++++++++++++++++++++++++++ (* link.sml *) import "a"; import "b"; import "c"; import "d"; structure A = A(); structure B = B(A); structure C = C(A); structure D = D(structure X = B structure Y = C); ++++++++++++++++++++++++++++++ The files are as follows: ++++++++++++++++++++++++++++++ (* a.sml *) import "a.sig"; functor A() = ... ++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++ (* b.sml *) import "a.sig"; import "b.sig"; functor B (X:ASIG) : BSIG = ... ++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++ (* c.sml *) import "a.sig"; import "c.sig"; functor C (X:ASIG) : CSIG = ... ++++++++++++++++++++++++++++++ ... Building the system as shown above led to LARGE heap sizes (and images generated by exportML). I suspected that this was due to the duplicated imports of the same signature file by many sml files. For example, "a.sig" is imported by "a.sml", "b.sml", "c.sml". To verify this, I wrote a function called "smartImport" which uses "use" to load files. It maintains an environment of files already loaded and avoids duplicate loading of files (code appears at end of message). I then replaced "import" by "smartImport" in all my source files and rebuilt. I found that the resulting image size was much smaller. The following results were obtained using an actual system with approx. 40 modules. For both cases, exactly the same source code was loaded and an image exported using "exportML". ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ exportML file size (bytes) Without smartImport (regular sep. comp.) 5799968 With smartImport 3063840 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ This is quite a significant saving. I would eventually like to have an improved "import" command; one that can avoid duplicated loading of files. I'm not so sure the technique I have used (i.e. using file names to determine if a file has already been loaded) is a general error-free solution. A combination of file name and file modification time may be better. So whenever "import" loads a file, it records the file name and the file modification time. The next time it encounters this file, it compares the saved modification time with the file's actual modification time. If the file is newer, it reloads the file else it skips the file. Has anyone else had such experiences with separate compilation? Any other suggestions for how to keep the heap size down? Jawahar Comments: [jgm] Gene Rollin's sourcegroup stuff is being designed to take care of this problem. Status: Fixed (defunct feature) --------------------------------------------------------------------------- 357. import broken Submitter: Richard O'Neill (rmo@sys.uea.ac.uk) Date: Tue Nov 13 10:44:42 GMT 1990 Version: 0.67 (not in 0.66) System: Sun4/SunOS 4.1 (probably irrelevant) Severity: Major Problem: Version 0.67 of Standard ML of New Jersey breaks 'import'. Import now seems to compile the file it is given but fails to introduce the declarations from that file into the environment. Transcript: unix% cat > example.sml signature Test = sig type foobar end unix% sml Standard ML of New Jersey, Version 0.67, 21 November 1990 val it = () : unit - import "example"; [reading example.sml] [writing example.bin... done] [closing example.sml] signature Test - signature CopyOfTest = Test; std_in:3.24-3.27 Error: unbound signature: Test - Comments: (guesses) Looking at differences between 0.66 & 0.67 I see that the way the environment is handled has changed. I suspect that this has something to do with it. Other information: The version I have built was made from the mo.sparc files and src from 'pub/ml/working' at princeton. Status: fixed (as of 0.69 anyway) --------------------------------------------------------------------------- 358. import & pervasives Submitter: Elsa Gunter elsa@research.att.com Date: 27 March 1991 Version: 0.68 System: mips Problem: import doesn't always get the pervasive types right Code: (* File: bug.sig.sml *) signature ASig = sig exception FOO of string end (* File: bug.sml *) import "bug.sig"; functor AFunc () = struct exception FOO of string end Transcript: Standard ML of New Jersey, Version 0.68, March 7, 1991 val it = () : unit - import "bug.sig"; [reading bug.sig.sml] [writing bug.sig.bin... done] [closing bug.sig.sml] signature ASig - import "bug"; [reading bug.sml] [reading bug.sig.bin... done] bug.sml:5.18-5.23 Error: unbound type constructor: string import: syntax or semantic error [closing bug.sml] IMPORT failed - Standard ML of New Jersey, Version 0.68, March 7, 1991 val it = () : unit - import "bug"; [reading bug.sml] [reading bug.sig.sml] [writing bug.sig.bin... done] [closing bug.sig.sml] [writing bug.bin... done] [closing bug.sml] signature ASig functor AFunc - import "bug"; [reading bug.bin... ] [import(s) of bug are out of date; recompiling] [closing bug.bin] [reading bug.sml] [reading bug.sig.bin... done] bug.sml:5.18-5.23 Error: unbound type constructor: string import: syntax or semantic error [closing bug.sml] IMPORT failed - Status: Fixed (as of 0.69) --------------------------------------------------------------------------- 359. indexing Submitter: Gene Rollins <rollins@cs.cmu.edu> Date: Mar 11, 1991 Version: 0.67 Severity: minor Problem: Indexing code doesn't handle all abstract syntax trees Code: Anything with an import clause in it. Transcript: Error: Compiler bug: Index2 Comments: Only happens when (!System.Control.indexing) = true Fix: In file build/index.sml, add three clauses for printDec, and eliminate the final wildcard clause. diff {old,new}/build/index.sml 160a161,162 > | printDec(FIXdec _) = () > | printDec(OVLDdec _) = () 161a164 > | printDec(IMPORTdec _) = () 163d165 < | printDec _ = ErrorMsg.impossible "Index2" Comment: Import will soon go away. Then this will be "not a bug". Status: fixed in 0.71 --------------------------------------------------------------------------- 360. bad error message when missing functor argument Submitter: Robert Harper (rwh@cs.cmu.edu) Date: Aug 29 1990 Version: System: Severity: minor Problem: Here's another bug report, this one relatively minor. The problem arises as follows. I have a build file which imports a bunch of files and then applies a bunch of functors to build the program. I changed one of the functors to take a parameter where it formerly had none. But I forgot to change the build file to plug in an argument. Here's what I get: /usr/rwh/courses/ic90/build.sml:56.5-56.10 Error: unmatched structure spec: Type Error: Compiler bug: inststr NULLstr [closing /usr/rwh/courses/ic90/build.sml] - It gives a reasonable message, then an unreasonable one. I've noticed versions of this where the "compiler bug" is "tyC" (or something close to that). My suspicion is that it has to do with the awful declaration-as-argument syntax for functor applications .... Code: Transcript: Comments: Fix: Status: probably fixed in 0.73, but can't tell (no source provided) --------------------------------------------------------------------------- 361. Error: Compiler bug: Functor.applyFunctor.insttyc Submitter: Elsa elsa@research.att.com Date: 8 March 1991 Version: 0.66 & 0.67 System: mips mips and Sun3 with SunOS 4.0 Problem: Error: Compiler bug: Functor.applyFunctor.insttyc Code: Status: R signature AA = sig datatype s = a of s end (* signature AA *) signature BB = sig structure A : AA end (* signature BB *) signature CC = sig structure B : BB type v end (* signature CC *) functor F (structure B : BB) : CC = struct structure B = B structure A = B.A open A type u = s end (* functor F *) structure C : CC = F (structure B = B); Transcript: - use "bug2.sml"; [opening bug2.sml] bug2.sml:19.5-24.7 Error: unmatched type spec: v bug2.sml:26.37 Error: unbound structure name: B bug2.sml:26.20 Error: unmatched structure spec: A insttyc: NULLtyc Error: Compiler bug: Functor.applyFunctor.insttyc [closing bug2.sml] - Status: fixed in 0.73 --------------------------------------------------------------------------- 362. missing primop in interp Submitter: John Reppy (jhr@cs.cornell.edu) Date: Jan 17 1991 Version: 0.67 System: Severity: Problem: Code: Transcript: Standard ML of New Jersey, Version 0.67, 21 November 1990 val it = () : unit - System.Control.interp := true; val it = () : unit - fun f x = Bits.notb x; Error: Compiler bug: bad primop in interp Comments: Fix: Status: fixed (as of 0.69) --------------------------------------------------------------------------- 363. bug in 0.69 interpreter Submitter: John Reppy (jhr@cs.cornell.edu) Date: June 17 1991 Version: 0.69 System: Severity: Problem: Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - app (fn x => x) ["abc", "def"]; val it = () : unit - System.Control.interp := true; val it = () : unit - app (fn x => x) ["abc", "def"]; uncaught exception Match - Comments: First fix the saving of lambda in interact.sml. Fix: Status: fixed in 0.70 --------------------------------------------------------------------------- 364. bug in lexgen doc Submitter: John Reppy (jhr@cs.cornell.edu) Date: June 5 1991 Version: System: Severity: minor Problem: The example of how to build a lexer is wrong (line 348), because the input file gets opened multiple times. val lexer = Mlex.makeLexer (fn x => input(open_in "f",x)) should be val lexer = Mlex.makeLexer (inputc (open_in "f")) This has confused at least one naive user. Code: Transcript: Comments: [jgm] according to Dave Tarditi, this has been fixed in the latest copy of the documentation. Fix: Status: fixed in 0.70 --------------------------------------------------------------------------- 365. fixed size of tuples causes bug Submitter: Jawahar Malhotra Date: 29 May 91 Version: 0.62 System: SUN SPARC, SUN OS 4.1 Severity: major Problem: A labeled record can have no more than 100 fields Comments: I was browsing the typechecker code (typing/typecheck.sml) and I noticed a constant "val maxFieldNum = 100," which I assume limits the number of slots a tuple is allowed to have. It would be best to avoid such hard-coded limits, but, if they must exist, they probably should be localized into a single structure, to allow easy modifications. - John Version 0.69 of SML/NJ: When compiling the following code, an "uncaught exception Subscript" occurs. If the number of elements in the tuple is reduced to 100 from 110, the exception no longer occurs. From: wright@rice.edu (Andrew Wright) fun g(f) = ( f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f() ); Fix: sort without an array Status: fixed in 0.71 --------------------------------------------------------------------------- 366. lookPath bug in 0.56 Submitter: James Shennan, University of Warwick, Coventry, CV4 7AL. tel: 0203 523523 Date: 29th January 1991 Version: 0.56 System: Severity: Problem: The two modules that follow were tested independantly and they both worked. The problem comes when they try and communicate. I have cut the modules down as much as possible and hope that the exact problem is clear to you (as it isn't to me!). I've been playing around with the two modules and found that they work okay in conjunction with eachother when the datatype node_seq in the NODE_SEQ module is not recursive. Code: ***************************************************************************** This is the Hierarchy structure that uses the sequence structure. ****************************************************************************** import "../sequence/sequence"; signature HIERARCHY = sig type Sequence datatype Hierarchy = EmptyHierarchy | Addlevel of Sequence * Hierarchy end functor Hierarchy(structure Node_Seq : NODE_SEQ) : HIERARCHY = struct type Sequence = Node_Seq.node_seq datatype Hierarchy = EmptyHierarchy | Addlevel of Sequence * Hierarchy end ****************************************************************************** And this is the Node_Sequence structure. ****************************************************************************** import "node"; signature NODE_SEQ = sig eqtype Element datatype node_seq = NIL | cons of Element * node_seq end functor Node_Seq(structure Node : NODE) : NODE_SEQ = struct type Element = Node.tYpe datatype node_seq = NIL | cons of Element * node_seq end **************************************************************************** This is the file that I 'use' to save typing. I have tried typing it in manually as well. **************************************************************************** import "../hierarchy/hierarchy"; structure n = Node(); structure ns = Node_Seq(structure Node = n); structure h = Hierarchy( structure Node_Seq = ns); open h; val seq = ns.cons("hello",ns.NIL); val H = Addlevel(ns.NIL,EmptyHierarchy); val HH = Addlevel(ns.NIL,H); val HHH = Addlevel(seq,HH); Transcript: Script started on Tue Jan 29 16:57:12 1991 warning: could not update utmp entry njsmlchmod: /dev/ttyp0: Not owner Variable syntax. emerald> njsml Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - use "vars"; [opening vars] [reading ../hierarchy/hierarchy.bin... done] signature NODE signature HIERARCHY signature NODE_SEQ functor Node functor Hierarchy functor Node_Seq structure n : sig eqtype tYpe end structure ns : sig datatype node_seq con NIL : node_seq con cons : Element * node_seq -> node_seq eqtype Element end structure h : sig eqtype Sequence datatype Hierarchy con Addlevel : Sequence * Hierarchy -> Hierarchy con EmptyHierarchy : Hierarchy end open h val seq = cons (-,NIL) : ns.node_seq val H = Addlevel (NIL,EmptyHierarchy) : Hierarchy val HH = Addlevel (NIL,Addlevel (NIL,EmptyHierarchy)) : Hierarchy val HHH = Addlevel (Error: Compiler bug: EnvAccess.lookPath [closing vars] - ^Demerald> ^Dexit Comments: Fix: Ask the submitter if it still happens in 0.73. Status: probably fixed --------------------------------------------------------------------------- 366. lookahead Submitter: Dave Berry <db@lfcs.edinburgh.ac.uk> Date: Jan 26 1991 Version: ? Severity: minor Problem: If I type the following simple program to either SML/NJ or Poly/ML, I get some interesting behaviour: (lookahead std_in; lookahead std_in); (I haven't tried this with Poplog ML or Edinburgh ML because they're only installed on our Suns, which have crashed.) If I give this program the input a it returns the string "a". This is the behaviour I expect - the first call looks at the next character but doesn't affect the state of the stream, so the next call finds the same character. (If you try this you'll have to type a semi-colon after the program finishes, because the compiler will read your input.) However, if I give the following input to the program <CTRL-D>a then it still returns "a". In other words the first call consumes the end-of-stream marker, changing the state of the stream. It's not at all clear to me that this is the desired behaviour. It's this behaviour that results in the problem with end_of_stream that I mentioned some weeks ago, because (end_of_stream i) is defined as (lookahead i = ""). I suggest that lookahead should never change the state of a stream, even when it finds an end-of-stream marker on an interactive stream. This may require some extra state information in the implementation of a stream, but that shouldn't be visible to the user. This would give more consistent behaviour, and would solve the problem with end_of_stream. It also means that I could get rid of the InStream and OutStream types in the Edinburgh library, making it quite a bit simpler to use (and maintain). Some interactive programs do have to consume end-of-stream markers on interactive streams. This can be done by calling read at the appropriate place, perhaps using a function like the following: fun consumeEOS i = if InStream.interactive i then if end_of_stream i then read i else "" else raise NotInteractive i; The only problem that I can see with this approach is that a program that tests for end_of_stream won't necessarily consume the end-of-stream marker with an explicit read, which means that the compiler will read it and exit. I can think of a couple of ways that an implementation could avoid this. The first is to consume an end-of-stream marker before reading a new program, thus requiring the user to type CTRL-D twice to exit (which might be safer anyway). The second is to require the user to call a specific exit function to exit the compiler. The third is to treat std_in specially, and to mark when an end-of-stream marker is encountered by a user calling lookahead as opposed to the compiler calling lookahead. I don't know how easy this would be to implement. To summarise, this gives a consistent behaviour to lookahead, and seems a far neater way of solving the end_of_stream problem than my previous suggestion. Status: fixed in 0.71 --------------------------------------------------------------------------- 367. Decstation mach recompolation to m68 Submitter: Gene Rollins <rollins@cs.cmu.edu> Date: Mar 13, 1991 Version: 0.67 Batch Compiler System: Decstation mach (cross compiler to m68) Severity: major Problem: Cross compiler halts with Getscratch Code: The 0.67 compiler sources Transcript 1: I added vertical ellipses to omit part that worked correctly. Standard ML of New Jersey, Version 0.67, 21 November 1990 (batch compiler) [setreducemore()] [reducemore := 0] [setrounds()] [rounds := 10] [setbodysize()] [bodysize := 20] [mBoot()] . . . [Compiling boot/math.sml] signature MATH structure Math boot/math.sml:290.4 Warning: match not exhaustive 0 => ... 1 => ... [closing boot/math.sml] [Failed on "~mBoot" with Getscratch] Transcript 2: Standard ML of New Jersey, Version 0.67, 21 November 1990 (batch compiler) [globalhandle := false] [markabsyn := false] [mBoot()] . . . [Compiling env/env.sml] structure Env [closing env/env.sml] [Failed on "!env/env.sml" with Getscratch] uncaught exception (Loader): Getscratch Comments: The Sun3 Mach batch compiler for m68 works fine. Status: fixed in 0.69, Appel suspects. --------------------------------------------------------------------------- 368. missing exceptions Submitter: Larry Paulson (larry.paulson@computer-lab.cambridge.ac.uk) Date: 16 Nov 90 Version: 0.69 System: Severity: minor Problem: You have most, but not all, of those silly arithmetic exceptions. Larry Code: Transcript: - Abs; std_in:7.1-7.3 Error: unbound variable Abs - Div; val it = exn : exn - Mod; val it = exn : exn - Quot; std_in:3.1-3.4 Error: unbound variable Quot - Prod; val it = exn : exn - Neg; val it = exn : exn - Sum; val it = exn : exn - Diff; val it = exn : exn - Floor; val it = exn : exn - Sqrt; val it = exn : exn - Exp; val it = exn : exn - Ln; val it = exn : exn Comments: Fix: edit perv.sml and perv.sig Status: fixed in 0.71 --------------------------------------------------------------------------- 369. bug in MLYACC Submitter: John Reppy (jhr@cs.cornell.edu) Date: May 29 1991 Version: 0.69 System: Severity: major Problem: I was compiling mlyacc with 0.69 and noticed a couple of problems. In addition to the syntax error in yacc.sml (lines 350-351), there is also a funny message being generated: [opening yacc.sml] $$ lookTycPath 1: 2 2 tyconInContext: [2] Code: Transcript: Comments: [jgm] See bugs 307 and 336 -- this may not be MLYACC's fault. Fix: see 336. Status: fixed in 0.71 --------------------------------------------------------------------------- 370. Wrong definition of div & mod in perv.sml Submitter: Andrzej Filinski <andrzej@cs.cmu.edu> Date: 3/16/91 Version: 0.67 System: All (verified on PMAX, Mach/4.3 BSD) Severity: major Problem: Wrong definition of div & mod in perv.sml Code: 0 div ~2 Transcript: - 0 div ~2; val it = ~1 : int - 0 mod ~2; val it = ~2 : int Comments: Definition (p.79) requires a result of 0 in both cases. Fix: In boot/perv.sml, "structure Integer = ...", replace < fun op div(a:int,b:int):int = < if a>=0 < then if b>=0 then InLine.div(a,b) < else InLine.div(a-1,b)-1 < else if b>=0 then InLine.div(a+1,b)-1 < else InLine.div(a,b) with > fun op div(a:int,b:int):int = > if b>=0 > then if a>=0 then InLine.div(a,b) > else InLine.div(a+1,b)-1 > else if a>0 then InLine.div(a-1,b)-1 > else InLine.div(a,b) Status: fixed in 0.71 --------------------------------------------------------------------------- 371. intmap bug Submitter: Chet Murthy (murthy@cs.cornell.edu) Date: 13 Jun 91 Version: System: Severity: Problem: I was using intmap to implement a hash table, and I found what appears to be a bug. Code: (* requires intmap.sig and intmap.sml to be loaded To see the bug, run "try 477 trace;" and "try 476 trace;" the variable longtrace is bound to an even longer trace. Each will, for each N in the list, add (N,CTR) to the intmap, and then increment CTR. Then each will dump the intmap with intMapToList, and compare the cardinality of the domain (computed by getting the first projection of each pair in the graph given by intMapToList and and uniquifying it) to the actual length of the list returned by intMapToList. The function repeated will print out all the pairs (N,V) such that N appears more than once in the graph. Try "repeated 476 trace" and observe that the output is empty, whereas "repeated 477 trace" produces "[(29,476),(29,316)]" meaning that both pairs showed up in the trace. *) (* splits a list into the first N elts and the tail *) fun chopList(0,l) = (nil,l) | chopList(n,h::t) = let val (m,l') = chopList(n-1,t) in (h::m,l') end fun member x nil = false | member x (h::t) = if x = h then true else member x t fun uniquize nil = nil | uniquize (h::t) = if member h t then uniquize t else h::(uniquize t) fun collect f l = fold List.@ (map f l) nil fun runTo n l = let val (pref,_) = chopList(n,l) val ctr = ref 0 val imap = Intmap.new(100,General.Match) fun go nil = () | go (h::t) = (Intmap.add imap (h,!ctr);inc ctr;go t) in (go pref;Intmap.intMapToList imap) end fun try n trace = uniquize(map #1 (runTo n trace)) = (map #1 (runTo n trace)) fun repeated n trace = let val graph = runTo n trace fun aux nil = nil | aux (h::t) = (if member h t then [h] else nil)@(aux t) fun find x nil = nil | find x ((a,b)::t) = (if x = a then [(a,b)] else nil)@(find x t) val repetitions = aux (map #1 graph) in collect (fn x => find x graph) repetitions end val trace = [26,98,96,64,32,52,62,91,23,53,41,30,58,67,29,16,37, 68,51,62,89,70,5,10,76,50,90,16,51,47,48,74,32,21, 68,33,55,58,19,12,19,81,60,31,38,15,45,69,32,19,38, 44,0,50,97,15,8,79,55,23,3,81,11,3,23,64,26,74,23, 57,93,69,41,66,19,96,20,63,25,90,8,44,98,98,82,40, 46,18,81,92,65,35,65,77,98,45,39,87,46,64,2,48,43, 2,79,83,25,41,42,98,71,39,44,65,40,77,54,32,12,15, 80,76,55,26,43,20,57,77,15,66,11,92,64,4,8,1,22,5, 66,39,48,17,72,41,76,28,56,41,6,69,89,31,38,44,51, 9,64,85,45,37,82,20,97,93,82,61,18,0,27,6,17,65,20, 23,0,23,39,98,66,75,54,23,19,77,96,57,78,22,50,30, 13,63,84,88,12,83,84,22,41,68,61,54,60,4,69,84,10, 21,50,35,28,89,11,62,12,75,69,80,95,6,98,94,2,84, 60,29,51,72,77,6,20,5,95,29,97,21,49,30,89,3,70,53, 28,74,37,59,96,22,52,65,6,98,91,22,95,8,7,65,60,61, 44,47,62,76,30,63,46,32,94,26,30,7,73,79,29,57,12, 15,14,57,9,25,72,89,36,87,57,66,87,59,26,26,26,16, 66,68,26,59,59,26,72,22,55,59,73,73,26,64,96,27,73, 96,96,26,15,43,29,96,48,48,26,71,8,84,48,68,68,26, 31,50,97,68,88,88,26,91,59,40,88,36,36,26,35,44,31, 36,16,16,26,39,49,88,16,48,48,26,67,99,21,48,26,27, 98,98,98,26,48,46,98,26,26,27,77,77,77,26,0,25,77, 26,27,15,92,92,26,61,71,92,26,27,81,81,81,26,48,19, 81,26,26,27,15,15,15,26,9,57,15,26,26,27,10,80,80,26, 25,48,80,26,26,27,24,24,24,26,23,76,24,26,26,27,99,76, 76,26,43,89,76,26,26,27,34,34,34,26,7,74,34,43,6,27, 45,26,91,91,26,91,64,91,26,26,27,31,31,31,26,31,54,31, 26,26,27,36,13,13,26,86,29] Transcript: Comments: Should fix intmap to not allow users to specify initial size. Fix: Don't use 100 as the initial size. Status: not a bug --------------------------------------------------------------------------- 372. open in signature causes compiler bug Submitter: Gene Rollins <rollins@cs.cmu.edu> Date: Mar 11 1991 Version: 0.67 Severity: major Problem: open in signature results in compiler reporting a bug Code: signature ARITH = sig structure Term : TERM open Term ... Transcript: - use "src-use/arith.sig.sml"; [opening src-use/arith.sig.sml] Error: Compiler bug: EnvAccess.openStructureVar -- bad access value [closing src-use/arith.sig.sml] Status: fixed (as of 0.69) --------------------------------------------------------------------------- 373. bug in printing fully qualified structure names Submitter: Andrew Tolmach (apt@princton.edu) Date: 16 Apr 91 Version: 0.69 System: Severity: minor Problem: prints qualified names in the wrong order on error. Looks like someone got the list backwards. Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - structure Fred = struct structure Bill = struct fun f x = x + 1 end end; structure Fred : sig structure Bill : sig...end end - open Fred.Bill; open Fred.Bill - f true; std_in:4.1-4.6 Error: operator and operand don't agree (tycon mismatch) operator domain: int operand: bool in expression: Bill.Fred.f true Comments: Appel says: these qualified names shouldn't be there anyway! The abstract syntax should in this case match the concrete syntax, so the message should say, "f true" not "Fred.Bill.f true". Fix: remove "qid@" from varApplied and strApplied in envaccess.sml Status: fixed in 0.71 --------------------------------------------------------------------------- 374. mod overflows on some negative numbers Submitter: Eric Cooper (ecc@cs.cmu.edu) Date: 01 May 91 Version: 0.66-0.69 System: Pmax, Vax, Sun4 Severity: major Problem: Code: Transcript: - val minint = ~1073741824; val minint = ~1073741824 : int - minint mod 10; uncaught exception Overflow Comments: The SML definition of div and mod is different than that typically provided by hardware, thus mod and div actually defined as fun op div(a:int,b:int):int = if a>=0 then if b>=0 then InLine.div(a,b) else InLine.div(a-1,b)-1 else if b>=0 then InLine.div(a+1,b)-1 else InLine.div(a,b) fun op mod(a:int,b:int):int = a-(a div b)*b (see boot/perv.sml). The "*" in mod is causing the overflow. You could use quot and rem, but they may not give you the answer you want: - ~1073741824 rem 10; val it = ~4 : int - John Fix: First, see the fix for bug 370. Second, use a separate case analysis for "mod", don't just call "div". Status: fixed in 0.71 --------------------------------------------------------------------------- 375. overflow bugs Submitter: John Reppy (jhr@cs.cornell.edu) Date: 6 Dec 1990 Version: 0.67 System: Severity: major? Problem: Dave Berry's library code trips over the following problem with large positive integers: Code: Transcript: Standard ML of New Jersey, Version 0.67, 21 November 1990 val it = () : unit - ~1073741822; val it = ~1073741822 : int - it+1; val it = ~1073741821 : int - ~it; val it = 1073741821 : int - 1073741821; uncaught exception Overflow Comments: dbm@research.att.com writes: > (2) I have had a runbind bug report for 0.69, but it may not be the > same bug you have seen. I would appreciate it very much if you could > send me formal bug reports on the Runbind and Overflow problems. We > can certainly cope with redundant bug reports! The easiest way to reproduce the Runbind exception is to try to load the portable version of the SML library into SML 0.69. I've also had it occur when I was doing something with returning options, but that code doesn't exist anymore (I changed the structure of the code and the problem went away). As far as the overflow is concerned: eXene -- version 0.2 (alpha) -- April 1, 1991 Concurrent ML, version 0.9.2, January 15, 1991 val it = () : unit - 1073741823; uncaught exception Overflow - 1024; uncaught exception Overflow <------ this shouldn't happen - Standard ML of New Jersey, Version 0.68, March 7, 1991 val it = () : unit - 1073741823; uncaught exception Overflow - 1024; uncaught exception Overflow <------ this shouldn't happen - Fix: Status: fixed as of 0.69? ([jgm] works on SGI) --------------------------------------------------------------------------- 376. empty signatures and functors, parsing Submitter: Nick Rothwell (nick@lfcs.ed.ac.uk) Date: 21 Nov 1990 Version: 0.66? Severity: minor Problem: SML/NJ accepts the following (both of which are not legal SML): signature S = sig end functor F() = struct end; val x = "A" ^ if true then "B" else "C"; Comment: [dbm] The first problem is an intensional divergence, the second is fixed as of 0.69. Status: fixed in 0.69 --------------------------------------------------------------------------- 377. prop.sml has bug Submitter: Date: Dec 25 1990 Version: 0.66 System: Severity: minor Problem: ../66/doc/examples/prop.sml doesn't correctly change to conjunctive normal form. (* exercise *) Code: Transcript: Comments: Fix: Put comment at top of prop.sml saying that it has bugs. Status: fixed in 0.71 (comment put in!) --------------------------------------------------------------------------- 378. Error: Compiler bug: Functor.applyFunctor.redoTycs 1 Submitter: Elsa Gunter (elsa@research.att.com) Date: Mar 8 1991 Version: 0.66 & 0.67 System: mips mips and sun3 with SunOS 4.0 Severity: major Problem: Error: Compiler bug: Functor.applyFunctor.redoTycs 1 Code: (* File bug1.sml *) signature AA = sig datatype s = a of t * s and t = b of s end (* signature AA *) signature BB = sig structure A : AA end (* signature BB *) signature CC = sig structure B : BB type u end (* signature CC *) functor F (structure B : BB) : CC = struct structure B = B structure A = B.A open A type u = t * s end (* functor F *) structure C : CC = F (structure B = B); Transcript: - use "bug1.sml"; [opening bug1.sml] bug1.sml:27.37 Error: unbound structure name: B bug1.sml:27.20 Error: unmatched structure spec: A Error: Compiler bug: Functor.applyFunctor.redoTycs 1 [closing bug1.sml] - Comments: Fix: Cascade Status: fixed in 0.71 --------------------------------------------------------------------------- 379. redundant patterns Submitter: John Reppy (jhr@cs.cornell.edu) Date: Jan 25 1991 Problem: I would like to suggest that the compiler reject redundant patterns as errors (possibly with a flag to generate only warnings to preserve compatibility with "The Definition"). The reason for this change is that it will force the user to deal with potential errors (warning messages usually get buried in the output). Often, a redundant pattern is the result of a mis-spelled constructor name, and so is actually an error (there is an example of this in the 0.67 version of the debugger). Transcript: I noticed the following redundant pattern warnings while compiling 0.67. The debugger ones are definitely an error. - John translate/translate.sml:227.30 Warning: redundant patterns in match VALtrans (PATH p) => ... VALtrans (INLINE eql) => ... VALtrans (INLINE neq) => ... VALtrans (INLINE i) => ... THINtrans (PATH p,v,locs) => ... CONtrans (d as DATACON {const=true,...}) => ... CONtrans (d as DATACON {const=false,...}) => ... VALtrans a => ... THINtrans (a,_,_) => ... --> _ => ... build/process.sml:334.32 Warning: redundant patterns in match ({access=SLOT s1,name=name},{access=SLOT s2,name=_}) => ... ({access=SLOT _,...},_) => ... ({access=PATH (:: (<pat>,<pat>)),...},{access=PATH (:: (<pat>,<pat>)),...}) => ... ({access=PATH _,...},_) => ... ({access=INLINE i1,...},{access=INLINE i2,...}) => ... ({access=INLINE _,...},_) => ... --> _ => ... debug/historystore.sml:371.1 Warning: redundant patterns in match (a,weak_desc) => ... --> (_,tag) => ... debug/historystore.sml:371.1 Warning: redundant patterns in match (a,weak_desc) => ... --> (_,tag) => ... debug/historystore.sml:371.1 Warning: redundant patterns in match (a,weak_desc) => ... --> (_,tag) => ... Status: not a bug (a suggestion) --------------------------------------------------------------------------- 380. regbind compiler bug Submitter: Eric Cooper, ecc@cs.cmu.edu Date: Dec 5, 1990 Version: 0.66 System: VAX and SPARC running Mach 2.5 Severity: major Problem: compiler raises Regbind; top-level dumps core Code: (* This example causes the compiler to raise Regbind on SML/NJ 0.66 on Sparc SML/NJ 0.65 on VAX After the exception message is printed, typing () to the top level causes an illegal instruction trap. It doesn't fail if: functor is replaced by a structure (name ^ "\n") is replaced by name (n mod period = 0) is replaced by (n + period = 0) the tail recursive call to proc () is removed *) functor Broken (S : sig val perform : (unit -> 'a) -> 'a end) = struct val period = 0 val name = "foo" val n = 0 fun proc () = (if n mod period = 0 then S.perform (fn () => print (name ^ "\n")) else (); proc ()) end (* Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - [opening bug.sml] [closing bug.sml] uncaught exception Regbind - (); SIGILL code 0x2 Process Inferior sml exited abnormally with code 3 *) Status: fixed? ([jgm] works on SGI) --------------------------------------------------------------------------- 381. saving registers for signal handler continuation Submitter: Andrew Tolmach (apt@princeton.edu) Date: 14 may 1991 Version: 0.69 System: Severity: major Problem: Andrew Tolmach discovered an interesting bug, which he and I traced further. Summary: At a heap-limit check (typically an add-to-limit-causing-overflow), there are two kinds of general-purpose registers: 1. Live Pointers or Tagged Integers. These get a 1 in the register mask. 2. Dead Pointers, Live Untagged Integers, or anything else. These get a 0. Thus, a 0 in the mask does NOT indicate "dead." Registers with a 1 in the mask should be forwarded (if pointers) by the G.C., and registers with a 0 should be preserved unchanged. Unfortunately, the function "make_ml_sigh_arg" was not preserving the 0-in-the-mask registers, so that the string-creation function create_s was losing a register if a signal occurred. Code: Transcript: Comments: From: David.Tarditi@LAMBDA.ERGO.CS.CMU.EDU Status: R You write: > Thus, a 0 in the mask does NOT indicate "dead." Registers with a 1 > in the mask should be forwarded (if pointers) by the G.C., and > registers with a 0 should be preserved unchanged. > > Unfortunately, the function "make_ml_sigh_arg" was not preserving the > 0-in-the-mask registers, so that the string-creation function create_s > was losing a register if a signal occurred. Is having ml_sigh_arg preserve all registers the right thing to do ? Maybe we should enforce the invariant that a 0 in the mask indicates "dead" ? The argument for doing this is that it makes signal handling cheaper in both time and space. Right now, make_ml_sigh_arg only has to save the number of used registers. It scans each bit in the mask to determine which registers to save until the remainder of the mask is 0, so it takes less time also, if live registers tend to be the lower numbered registers (as they do with the current register allocator). The argument for not doing this is that is allows us to do "representation analysis", i.e. place untagged integers in registers across procedure boundaries. I don't know what the performance gain from this will be. Dave From: Andrew Appel <appel@Princeton.EDU> John Reppy has found that signal-handling overhead isn't too bad (3% for 20-millisecond timer interrupts on a SPARC), and saving a few extra register shouldn't make a huge difference. I would certainly hate to rule out passing untagged integers across procedure boundaries. Fix: Status: not yet a bug --------------------------------------------------------------------------- 382. missing \n on infix echo Submitter: Eric Cooper (ecc@cs.cmu.edu) Date: Jun 11 1991 Version: 0.69 System: Severity: minor Problem: First, a trivial one: the top-level omits the \n when echoing global infix declarations: Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - infix operator; infix operator- (In 0.65, infix declarations weren't being printed at all.) Comments: Fix: insert newline() at end of printFixity function in print/printdec.sml Status: fixed in 0.71 --------------------------------------------------------------------------- 383. open in nested structures fails with "Runbind" Submitter: Eric Cooper (ecc@cs.cmu.edu) Date: Jun 11 1991 Version: 0.69 System: Severity: major Problem: The "print x" below fails with exception "Runbind". Code: structure S = struct val x = 0 end; structure SS = struct structure S = S end open S; open SS; print x; (* fails with exception Runbind *) Transcript: Comments: This worked OK in 0.65. Among other things, Paulson's Isabelle examples now fail to compile, which is how I tripped over this. Fix: Appel partially diagnosed this, sent mail to MacQueen Status: fixed in 0.73 --------------------------------------------------------------------------- 384. signal handler never re-installed Submitter: Manuel Fahndrich (mf39@andrew.cmu.edu) Date: 6/4/91 Version: 0.66 0.67 System: DECstation 3100 (Mach and BSD UNIX 4.3) Problem: The signal handlers only get called the first time they are installed. Once setHandler(signal, NONE) is executed and then setHandler(signal, SOME handler), the signal is ignored. Tested on signals (SIGIO, SIGINT, SIGALRM) Transcript: fun ioh (_, k) = (print "SIGIO\n"; k); System.Signals.setHandler (System.Signals.SIGIO, SOME ioh); <ok, this works> System.Signals.setHandler (System.Signals.SIGIO, NONE); <ok, ignored> System.Signals.setHandler (System.Signals.SIGIO, SOME ioh); <wrong, still ignored!!!> Comment: The inqHandler returns the correct handler function at the end. [jgm] The following code really exercises the bug: open System.Signals; setHandler(SIGINT, NONE); inqHandler(SIGINT); (* core dumps *) Code for setHandler and inqHandler is simple enough to figure that the bug is probably in the code generator -- it's broken on Mach and Irix, so the OS is not to blame. Also, ripping the signal handling code in perv.sml out and compiling it on top of the pervasives makes the bug go away. (1) Suppose we do : open System.Signals; open System.Timer; val setitimer = System.Unsafe.CInterface.setitimer; fun setTimer msec = (setitimer(0,TIME{sec=0,usec=1000*msec}, TIME{sec=0,usec=1000*msec})); setHandler(SIGALRM,SOME(fn (_,k) => (print "hi!\n";k))); setTimer 500; This will print hi! twice a second (on cs or elan) or (roughly speaking) when return is hit (on haven), more or less as expected. (2) Now suppose we do : setHandler(SIGALRM,NONE); setHandler(SIGALRM,SOME(fn (_,k) => (print "lo!\n";k))); On all machines, this has no visible effect; that is, lo! is not printed. (3) But if we then do: System.Unsafe.CInterface.c_function "enablesig" (3,true); we do start seeing lo! just as we saw hi! before. Finally, and most excitingly, if we do (1) followed by: setHandler(SIGALRM,NONE); inqHandler SIGALRM; we get the following results: on haven and k2 (both versions): Bus Error on elan: - Fixed up unaligned data access for pid 16679 (sml) at pc 0x417ed0 val it = SOME fn : (int * (unit) cont -> (unit) cont) option on cs: val it = SOME fn : (int * (unit) cont -> (unit) cont) option [jgm] See bug 397 for the probable cause... Status: should be fixed in 0.70 --------------------------------------------------------------------------- 385. SIGHUP, SIGQUIT, SIGTERM ignored sometimes Submitter: Mark Foster (mark@central.cis.upenn.edu) Date: Nov 15 1990 Version: 0.66 System: Severity: minor Problem: It appears that some signals get ignored when they shouldn't. In particular, SIGHUP SIGQUIT and SIGTERM don't get properly delivered when the parent process of sml exits in certain ways. As a result, the sml process remains, sometimes dormant, and sometimes in a spin loop (continuous select() calls, trying to output a message, but it can't because it's psuedo tty is "gone"). The easiest way we've found to demonstrate the problem is via telnet % telnet me Trying 127.0.0.1 ... Connected to LOCALHOST.UPENN.EDU. Escape character is '^]'. (login stuff deleted) % sml Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - now, escape back to telnet, then close the connection ^] telnet> c the sml process does not exit. WORKAROUNDS: We have two possible workarounds to this problem. Fundamentally, the output that's trying to happen probably needs to be fixed. Either to detect when it cannot successfully output or to just give up at some point. The following two approaches don't do fix the problem, they just bandaid around it. Both methods "cure" the problems we've been experiencing. Method 1: Change runtime/signal.c to disallow redefining of the signals used to shutdown a child process % diff signal.c.orig signal.c 210c210,214 < case ML_SIG_ENABLED: SETSIG (sig, sig_handler, SIGMASK); break; --- > case ML_SIG_ENABLED: if ((sig != SIGQUIT) && > (sig != SIGHUP) && (sig != SIGTERM)) { > SETSIG (sig, sig_handler, SIGMASK); > } > break; 234c238,241 < SETSIG (sig, sig_handler, SIGMASK); --- > if ((sig != SIGQUIT) && > (sig != SIGHUP) && (sig != SIGTERM)) { > SETSIG (sig, sig_handler, SIGMASK); > } Method 2: Change boot/perv.sml to not attempt to output a message on quit % diff perv.sml.orig perv.sml 1871,1873c1871 < fun quit s _ = ( < output(std_err, s); output(std_err, " (no coredump)\n"); < System.Unsafe.CleanUp.shutdown()) --- > fun quit s _ = (System.Unsafe.CleanUp.shutdown()) Date: Sun, 18 Nov 90 09:58:41 -0500 From: jhr@cs.cornell.edu (John Reppy) Subject: Re: signal info from Mark Foster at Penn. Status: R I've seen this effect, but I never thought about it enough to realize what was going on. His first solution is an awkward way to say the ML can't handle SIGHUP, SIGQUIT and SIGTERM; I like to avoid that. His second solution is better; but there probably should be a warning somewhere abut the problems with SIGHUP. - John From: jhr@cs.cornell.edu (John Reppy) Subject: Re: signal info from Mark Foster at Penn. Cc: mark@central.cis.upenn.edu Status: R I think that this problem is a bug in the way select works. If you do a select on a closed file, it fails with EBADF; I think it should do the same if the ptty has gone away. But we live in an imperfect world, so I recommend the following fix: Replace the function quit (at the end of perv.sml) with the following code: fun quit s _ = let val msg = (s ^ " (no coredump)\n\000") in (* use write, since IO.output will block if we've lost the ptty *) System.Unsafe.SysIO.write(2, System.Unsafe.cast msg, size msg) handle _ => (); System.Unsafe.CleanUp.shutdown() end Status: fixed (0.69) --------------------------------------------------------------------------- 386. printing bug with abstype Submitter: *jhr$ Date: Nov 8 1990 Version: 0.69 System: Severity: minor Problem: Notice the misplaced white space: - abstype 'a foo = Foo of 'a with end; type'a foo Code: Transcript: Comments: Fix: search for "type" in print/printdec.sml (also "eqtype") Status: fixed in 0.71 --------------------------------------------------------------------------- 387. arrays on Sparc Submitter: ark Date: Feb 12 1991 Version: 0.66 System: Sparcstation Severity: major Problem: dumps core when allocating large array Code: array(10000000,0) Transcript: Comments: Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- 388. * as label of record Submitter: Nick Rothwell (nick@lfcs.ed.ac.uk) Date: 8 Nov 90 Version: System: Severity: minor Problem: SML/NJ doesn't allow { * = "Hello" } as an expression. It should; after all, "*" is (chortle) just an ordinary identifier. Code: Transcript: Comments: Fix: Status: fixed (as of 0.69) --------------------------------------------------------------------------- 389. stats Submitter: Andrew Appel (appel@princeton.edu) Date: Apr 3 1991 Version: 0.66-0.69 System: Severity: minor Problem: Bug report: versions 0.66-0.69 System.Stats.execution (as reported in "summary()") starts out negative. Caused by the following sequence in "interact.sml": t := current cpu usage; exportML; t' := current cpu usage; System.Stats.execution := t'-t But of course, t' is less than t IN THE NEW PROCESS. Code: Transcript: Comments: Fix: Appel has a fixt for this that will go into 0.70 Status: fixed in 0.70 --------------------------------------------------------------------------- 390. Submitter: bpwing@phoenix.princeton.edu Date: March 19, 1991 Version: 0.65-0.69 System: SUN 4, v4.1? Severity: minor Problem: when reporting error positions, tabs are treated as single characters instead of being expanded Comments: [jgm -- this seems correct to me...] Status: not a bug --------------------------------------------------------------------------- 391. truncate Submitter: David Taridti (dtarditi@cs.cmu.edu) Date: Apr 10 1991 Version: 0.69 System: Severity: major Problem: The function truncate does not work properly for large real numbers. For example, truncate of 4 billion yields a negative integer when it should raise the exception Overflow: Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - truncate(4000000000.0); val it = ~294967296 : int Comments: Status: fixed in 0.71 --------------------------------------------------------------------------- 392. two type constraints Submitter: Larry Paulson (lcp@computer-lab.cambridge.ac.uk) Date: 14 Nov 90 Version: 0.66 System: Severity: minor Problem: As I understand the Definition, Poly/ML is correct. Two type constraints might be handy if the program involves a lot of type synonyms. Comments? Code: Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 - 0 : int : int; std_in:2.9 Error: syntax error found at COLON Poly/ML v1.89 - Definition of SML Version 4 > 0 : int : int; val it = 0 : int Comments: Fix: Status: fixed (as of 0.69) --------------------------------------------------------------------------- 393. type abbreviations not transparent Submitter: Chris Okasaki (cokasaki@cs.cmu.edu) Date: 11/16/90 Version: 0.65 Severity: minor Problem: type abbreviations not transparent In particular, when the type abbreviation takes an argument which does not appear on the right hand side of the abbreviation, any type which appears in that position should be completely irrelevant. But in the current implementation this is not true. Code: type ('a,'b) bogus = 'a; val x = 0 : (int,int) bogus; (* really int *) val y = 1 : (int,int list) bogus; (* really int *) fun f (x:'a,y:'a) = (); (* force the types to unify *) f (x,y); (* unify (int,int) bogus and (int,int list) bogus *) (* should be equivalent to unifying int with int *) (* but it's not *) Transcript: Standard ML of New Jersey, Version 0.65, 10 September 1990 val it = () : unit - type ('a,'b) bogus = 'a; type ('a,'b) bogus = 'a - val x = 0 : (int,int) bogus; val x = 0 : (int,int) bogus - val y = 1 : (int,int list) bogus; val y = 1 : (int,int list) bogus - fun f (x:'a,y:'a) = (); val f = fn : 'a * 'a -> unit - f (x,y); std_in:3.1-3.7 Error: operator and operand don't agree (tycon mismatch) operator domain: (int,int) bogus * (int,int) bogus operand: (int,int) bogus * (int,int list) bogus in expression: f (x,y) - Comments: Interestingly enough, this doesn't seem to happen when you have a unary type abbreviation like type 'a bogus = int The problem seems to boil down to WHEN you project through abbreviations (i.e. when you do the "macro" expansion). There seems to be at least two possibilities, project through before a unification containing this type, or attempt to unify with this type and project through only if this fails. As long as every argument to the type abbreviation also appears in the expanded form, the two are equivalent. When an argument DOESN'T appear in expanded form, the second approach (which is the approach currently being used) causes problems. As is evident in the above example, it causes the typechecker to unify things which should not be unified. The following code from unify.sml (in unifyTy) is where the problem is: | (CONty(tycon1, args1), CONty(tycon2, args2)) => if eqTycon(tycon1, tycon2) -----> then unifyArgs(args1, args2) else (unifyTy(reduceType ty1, ty2) handle ReduceType => unifyTy(ty1, reduceType ty2) handle ReduceType => raise Unify("tycon mismatch")) The point marked is where the damage is done. If both types have the same abbreviation constructor, unification will blithely go ahead and try to unify ALL of the arguments, even though some of them might be irrelevant because they are unused. Fix: Three possibilities: 1. Decide that this is a "feature", that you really don't want (int,int) bogus to unify with (int,int list) bogus. However, I would argue that if this is what you want, you should be using the datatype facility, not the type facility. 2. Forbid type abbreviations which do not use all their arguments. This is somewhat unsatisfying since, although human programmers will probably not produce abbreviations like this, it is easy to imagine automatic programming utilities (like Lex or Yacc) that MIGHT produce such code. 3. Perform abbreviation expansion BEFORE unifying an abbreviated type with anything except a type variable (you would want to unify the type variable with the abbreviated type so that it can be printed correctly). The best way to do this is probably to define a new constructor for the type "ty" called something like ABBREVty of tycon * tylist * ty where the tycon is the abbreviation constructor tylist are the constructor's arguments and ty is the "macro expanded" type Then, in unifyTy, you could have (right after the two VARty clauses) | (ABBREVty(_,_,ty),_) => unifyTy(ty,ty2) | (_,ABBREVty(_,_,ty)) => unifyTy(ty1,ty) to project through the abbreviation appropriately. The catch to this is that you can then produce circular types so you would have to perform an occur check during type printing. For instance, consider the following: type ('a,'b) bogus; fun f (x:'b,y:('a,'b) bogus) = (); fun g x = f (x,x); What is the type of g? Really, it's 'a->unit but internally it's something like (pardon the abuse of notation): ABBREVty(bogus,['a,*],'a) --> unit where the * marks a circular reference back to the ABBREVty object. Obviously, a naive attempt to print this type will infinite loop-- hence the requirement for an occur check during type printing. Status: fixed in 0.74 (dbm) --------------------------------------------------------------------------- 394. strange message in 0.66 typechecker Submitter: John Reppy (jhr@cs.cornell.edu) Date: 6 Nov 1990 Version: 0.66 Severity: minor Code: Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - signature SAMPLER = = sig = type time sharing type time = System.Timer.time = val init : unit -> unit = val sample : (time * int * int) -> unit = end; signature SAMPLER = sig isEqTycon 1 UNDEF type time val init : unit -> unit val sample : time * int * int -> unit end - Status: fixed (as of 0.69) --------------------------------------------------------------------------- 395. weakness constraint problem Submitter: John Reppy (jhr@cs.cornell.edu) Date: Mar 18 1991 Problem: I'm having trouble with a weakness constraint, and I don't understand it. I have a function at top-level of a module, which the typechecker gives the type val attach : 'aU CML.chan * widget_t * mbutton_t * 'aU menu_t -> widget_t My memory is that the 'aU is an internal type variable? Anyway, attach calls another function taht also has an 'aU in its type; by adding a type constraint to the other function, then things compile. Anyway, this seems like a bug (and I think I've run into it before). Code: Transcript: Comments: Here is a smaller example that triggers the bug. The offending line is marked by "(** THIS DOESN'T WORK **)" signature INTERNAL_CML = sig type 'a event val sync : 'a event -> 'a end functor ConcurML () : INTERNAL_CML = struct exception Never and Escape exception Sync (* for signature compatability *) datatype evt_sts = EVT_ANY | EVT_READY | EVT_BLOCK type 'a base_evt = { pollfn : unit -> evt_sts, dofn : unit -> 'a, blockfn : bool ref -> 'a } datatype 'a event = EVT of 'a base_evt list local datatype 'a ready_evts = NO_EVTS (* no ready events *) | ANY_EVTS of (int * (unit -> 'a) list) (* list of ready anyevents *) | RDY_EVTS of (int * (unit -> 'a) list) (* list of ready events *) fun extract _ = NO_EVTS (* Generate index numbers for "non-deterministic" selection. We use a * round-robin style policy. *) val cnt = ref 0 fun random i = let val j = !cnt in cnt := j+1; (j mod i) end fun selectEvt (_, [f]) = f() | selectEvt (n, l) = (nth(l, random n)) () in (* sync : 'a event -> 'a *) fun sync (EVT []) = raise Never (** THIS DOESN'T WORK **) (*fun sync ((EVT []) : 'a event) = raise Never*) (** THIS WORKS **) | sync (EVT el) = ( case (extract el) of NO_EVTS => callcc (fn sync_k => let val evtflg = ref false fun log ({blockfn, ...} : 'a base_evt)= (throw sync_k (blockfn evtflg)) handle Escape => () in app log el; (*atomicDispatch()*) raise Sync end) | ANY_EVTS anyevts => selectEvt anyevts | RDY_EVTS evts => selectEvt evts) end (* local *) end (* functor ConcurML *) Comment: This is really the way that user-bound type variables are supposed to work! Status: not a bug --------------------------------------------------------------------------- 396. unbound variables should have type ERRORty Submitter: Dave MacQueen (dbm@research.att.com) Date: May 7 1991 Version: 0.66? Severity: minor Problem: An unbound variable should have type ERRORty rather than UNDEFty so that spurious secondary errors can be avoided. E.g. foo 3; Error: unbound variable foo Error: operator is not a function operator: undef in expression foo 3 Status: fixed (as of 0.69) --------------------------------------------------------------------------- 397. Unsafe.update with constant Submitter: Andrew Tolmach (apt@princeton.edu) Date: Mar 18 1991 Version: 0.69 System: Mips Severity: critical Problem: from Appel: Andrew Tolmach discovered the following bug, and I've tracked it down. Unsafe.update is unreliable on the MIPS when the value stored is a constant. (The same temporary is used twice in mips.sml). I'll fix this for the next version; in the meantime, use Array.update. Code: Transcript: Comments: [jgm] This is probably causing the bug in the signal handling routines. See bug 384 Fix: Appel and Tolmach have the fix, will install in 0.70 Status: fixed in 0.70 --------------------------------------------------------------------------- 398. use and pathnames Submitter: ark Date: May 13 1991 Version: 0.66 Severity: minor Problem: A reminder: SML still doesn't interpret pathnames in "use" calls relative to the correct directory. Comments: Should be taken over by sourcegroup mechanisms. Fix: make "use" accumulate filepaths (using filepaths.sig) Status: open --------------------------------------------------------------------------- 399. Vax dumps core Submitter: David Tarditi (dtarditi@cs.cmu.edu) Date: Mar 14 1991 Version: 0.67 System: Vax Severity: critical Problem: The following piece of code causes version 0.67 of the compiler to dump core on Vaxes running Mach: - val s = "a"; - s; Segmentation fault (core dumped) Code: Transcript: Comments: Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- 400. problem parsing weak types Submitter: John Ophel jlophel@watmsg.waterloo.edu Date: 9/11/90 Version: 0.66 System: Vax, Unix Severity: minor Problem: weak type variables incorrectly parsed Transcript: - fun f (x:'10000000a) = x; val f = fn : 'a -> 'a - fun f (x:'10000001a) = x; std_in:1.5-1.24 Error: pattern and constraint don't agree (weakness violation) pattern: 'Z constraint: '10000001aU in pattern: x : '10000001aU Fix: In mkUBOUND (basics/typesutil.sml), weakness of more than 900000 should be illegal. Also note that the type variable '10000000000000a will cause an uncaught Overflow, which should be caught in this function. Status: fixed in 0.71 --------------------------------------------------------------------------- 401. Imperative types in SML/NJ 0.66 Submitter: Dave Berry <db@lfcs.edinburgh.ac.uk> Date: 14 Feb 91 Version: 0.66 System: Severity: Problem: The following program compiles under Poly/ML 1.86, but fails to compile under SML/NJ 0.66. fun create (x:int) (y:'_a) :'_a Array.array = Array.array (x, y) type ('a,'b) table = ('a*int*'b) list Array.array val defaultSize = 97 fun createDefault (sample'value :'_a) :(string, '_a) table = let val mt = [] : (string * int * '_a) list in create defaultSize mt end It will compile if Array.array is used directly in place of the curried version. It will also compile if createDefault is given an extra parameter, either before or after the existing one. This is the simplest example I've run across of SML/NJ failing to type correct SML use of imperative types. It's fairly simple in this case - it only took me a day to get the case this simple - but I've come across at least one other example that I've just given up on. I remember Dave MacQueen and mads Tofte discussing a bug in the SML/NJ algorithm at the Edinburgh Workshop. Is there any chance of a fix? Dave. From: jhr@cs.cornell.edu (John Reppy) This problem was pointed out by Jim O'Toole. Anyway, it was fixed in 0.67: Standard ML of New Jersey, Version 0.68-JHR, January 25, 1991 val it = () : unit - fun create (x:int) (y:'_a) :'_a Array.array = Array.array (x, y) = type ('a,'b) table = ('a*int*'b) list Array.array = val defaultSize = 97 = fun createDefault (sample'value :'_a) :(string, '_a) table = = let val mt = [] : (string * int * '_a) list = in create defaultSize mt = end; val create = fn : int -> '1a -> '1a array type ('a,'b) table = ('a * int * 'b) list array val defaultSize = 97 : int val createDefault = fn : '1a -> (string,'1a) table - Status: fixed (as of 0.67) --------------------------------------------------------------------------- 402. local non-declarations Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 30/1/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: some declarations not accepted Code: local val x = 5 in 20 + x end; Transcript: - local val x = 5 in 20 + x end; std_in:1.21 Error: syntax error found at INT Comments: Not sure this is a bug, but the SML documents are not clear about this. According to my interpretation of the standard grammar, this declaration should be equivalent to the following: - local val x = 5 in val it = 20 + x end; val it = 25 : int Fix: expressions are considered as declarations ONLY at top level. Status: not a bug ------------------------------------------- 403. 0.0/0.0 not properly handled Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 30/1/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: 0.0/0.0 not properly handled Code: 0.0/0.0 Transcript: - 0.0/0.0; strange floating point error (* and sml exits *) Comments: 0.0/0.0 is generally considered in implementations of reals as an "invalid operation" rather than a "division by zero" (exception code FPE_FLTOPERR_TRAP on SUNs OS 4.0). I did not checked the effect of 0.0/0.0 on other targets than SUN 4s, but it might have strange effects too; Fix: Status: fixed (as of 0.69) --------------------------------------------------------------------------- 404. std_out not flushed on read from std_in Submitter: Kim Dam Petersen (kimdam@sun.tfl.dk) Date: June 1991 Version: 0.66 System: all Severity: minor Problem: std_out not flushed on read from std_in Comments: As printing on the standard output and error streams usually are flushed automatically I would suggest that this should be part of the standard behaviour of these stream. It seems that NJ/ML delays output flushing until the computation of a top level expression has completed. As mentioned above flushing should be performed immediately. A temporary solution in NJ/ML is to redefine the `output' function, such that the predefined `flush_out' is automatically called: val output = fn(s,t) => (output(s,t); flush_out s) Future call of `output' will print the text immediately. Status: fixed in 0.71 --------------------------------------------------------------------------- 405. identifiers starting with underscores are incorrectly allowed Submitter: Mick Francis (Abstract Hardware) Date: August 1991 Version: 0.66 System: all Severity: minor Problem: identifiers starting with underscores are incorrectly allowed Status: fixed in 0.73 --------------------------------------------------------------------------- 406. funny signatures in 0.71 Submitter: John Reppy Date: August 1991 Version: 0.71 System: all Severity: minor Problem: Array.tabulate and String.chr have wrong types in initial environment Status: fixed in 0.73 --------------------------------------------------------------------------- 407. create_v_v for SPARC Submitter: Juergen Buntrock TUB, jubu@cs.tu-berlin.de Date: Tue Sep 24 19:23:13 MET DST 1991 Version: 0.73 System: sun4c SUNOS 4.1.1 Severity: major Problem: The mask is not set in create_v_v (SPARC.prim.s) segmentation fault in collect_roots in callgc.c Fix: diff -c SPARC.prim.s.org SPARC.prim.s *** SPARC.prim.s.org Fri Aug 23 20:33:54 1991 --- SPARC.prim.s Tue Sep 24 19:11:30 1991 *************** *** 476,481 **** --- 476,483 ---- nop 4: CONTINUE + .word closmask /* reg. mask */ + .word 0 3: add %g0,0,%g0 /* nop to get PC adjust right */ Status: Fixed in 0.74 --------------------------------------------------------------------------- 408. feedback from module system Submitter: tmb@ai.mit.edu Date: 08/03/91 Version: 0.70 System: Sun4/OS4.1.1 Severity: cosmetic, but important I have been playing around with building functors that abstract various notions of "iteration", "array", "sequence", and "index" (ultimately, this will hopefully provide a nicer alternative to the equivalent data structures in the current SML library). In general, using the ML module and type system for this seems straightforward and natural, and I'm much more pleased with the way I can design this code in SML than with similar code that I have written in Scheme, CommonLisp, and C++. However, I have also come across some cosmetic but (to me) important problems with the NJ/SML module system. Some of the problems are that the system isn't telling me enough about the identity of objects to allow me to debug the code without having to guess much; something analogous to the LispMachine inspector and mouse sensitivity would ultimately be very useful, but for the time being, just reporting unique tags for objects instead of "?" would be sufficient. Some of this might also be a question of style, but my ignorance is partially due to the fact that the only uses of the module system that I have seen have been rather simple and straightforward (even if they involve lots of code). I'd appreciate your feedback. Thanks, Thomas. PS: I can send you the complete code if you are interested, but it is still more of a sketch or prototype. = 1 ================================================================ I have a functor which generates iteration constructs for some data type that it is handed (e.g., it generates "fold", "apply", etc. for lists and arrays). It is very confusing that the types that the system reports for the functions generated by this functor involve types of the form "('a,'b) value" and "('a,'b) index". It would be much better if the types were reported in their true form. signature S = sig type ('a,'b) data end; functor F(structure X:S) = struct fun f(x:('a,'b) X.data):('a,'b) X.data = x end; structure A = struct type ('a,'b) data = 'b list end; structure B = F(structure X=A); - B.f([1]); val it = [1] : ('a,int) A.data - What I would want is: - B.f([1]); val it = [1] : int list - Obviously, which form one wants depends on the exact use that a functor is going to be put to. There should be a mechanism for me to specify in the type binding which form of reporting I prefer. = 2 ================================================================ Another problem that I have encountered is that it is nearly impossible to figure out what goes wrong with complicated functor applications with the current level of reporting: elements of intermediate structures are now often only reported as "?.KeyIndexing.foo", and it isn't helpful if the compiler tells you that "?.KeyIndexing.foo" is a different type from "?.KeyIndexing.foo". It would be much more convenient if there was an option to the compiler that would trace and report functor applications, and if the printer gave unique identities to structures, even temporary ones. Something like: - use "foo"; [Applying functor F<10> to structure <1001> giving structure <347> bound to structure T] [Applying functor G<11> to structure <66> giving structure <67> bound to structure T.M] [Applying functor G<11> to structure <33> giving structure <68> bound to structure T.M] - T.i; val it = SOMETHING : <11>.my_type; - Printing unique ID's for structures (and, for that matter, for other objects) shouldn't be hard, and it makes debugging so much easier. = 3 ================================================================ When writing signatures for functors that generate polymorphic functions, I seem to have to define types that carry around one type variable for each polymorphic type, e.g.: signature BASICACCESS = sig type ('a,'b) point type ('a,'b) value type ('a,'b) index type ('a,'b) range val first: ('a,'b) range -> ('a,'b) index val succ: ('a,'b) index -> ('a,'b) index val done: ('a,'b) index -> bool val mkindex: ('a,'b) point * ('a,'b) range -> ('a,'b) index val at: ('a,'b) index -> ('a,'b) value end; Most of the polymorphic functions that get generated from BASICACCESS structures will never need both type variables, while others may need more than two. For example, structure BasicListIndex = struct type ('a,'b) point = 'a list type ('a,'b) value = 'a type ('a,'b) index = 'a list type ('a,'b) range = 'a list fun first x = x val succ = tl val done = null fun mkindex(x,y) = x fun at x = System.Unsafe.cast (hd x) (* bug in NJSML .70 type checker ? *) end; structure BasicArrayIndex = struct type ('a,'b) point = int type ('a,'b) index = int * int type ('a,'b) range = int fun first(limit:('a,'b) range):('a,'b) index = (0,limit) fun succ((x,limit):('a,'b) index):('a,'b) index = (x+1,limit) fun done((x,limit):('a,'b) index):bool = x>=limit fun at x = x fun mkindex(x,r) = (x,r) fun index1((x,_):('a,'b) index) = x end; Carrying around the dummy type variables on types like "('a,'b) point" is a bother. Perhaps a simple solution would be to allow the user to omit type variables if they are specified as wildcards, e.g., "type ('_,'_) point = int" can be used simply as "val x : point" with the compiler inserting the missing (wildcard) type variables by convention. More generally, it would seem to be nice if type constructors could take variable numbers of arguments, and if they could pass their argument lists around as complete entities (analogous to passing around tuples of arguments in ML). Another possibility would be to allow "free" type variables: type point = '_ list This would simply be syntactic sugar for type 'a point = 'a list and the compiler would implicitly provide a dummy argument to "point" wherever it is used. However, this may break other parts of the type or module system. Point 3 is really about a basic problem with the current way signatures and functors handle types, not about "'_". Essentially, I want to write functors that generate objects that are polymorphic in different ways, e.g., that sometimes generate a function "f : 'a -> 'a" and sometimes "f : 'a -> 'b". The only way I could find of writing signatures for such functors is to make both the LHS and the RHS types (e.g. type ('a,'b) arg; type ('a,'b) result) that depend on two type variables and instantiate them in the matching structures to the correct types. This causes a number of problems that I mentioned in my previous message. Another possibility would be to allow a function of type "'a -> 'a" to match a type specification "'a -> 'b", but that does not currently work. Functors that generate functions that are polymorphic in different ways are very important, and, one way or another, SML must make this more convenient than it is right now. Thanks, Thomas. = 4 ================================================================ A related problem is that nongeneric weak type variables generate an error even if they are never used: - val x: '0a t = 3; std_in:3.1-3.16 Error: nongeneric weak type variable x : '0aU t - I think you can guess from the above structures and functors how such non-generic weak type variables can pop up unexpectedly (they are easy to fix for the user, by simply giving a type to the value, but it seems odd for a user of, say structure "Array2D" to have to specify some type as "(unit,int) array" just to create an array of type "int array"). = 5 ================================================================ A minor problem with wildcard type variables: - type ('_,'_) a; std_in:7.7-7.11 Error: duplicate type variable: '1 std_in:7.7-7.11 Error: duplicate type variable: '1 std_in:7.7-7.11 Error: duplicate type variable: '1 std_in:7.7-7.11 Error: duplicate type variable: '1 std_in:7.7-7.11 Error: duplicate type variable: '1 - I think the "'_" should refer to a new type variable every time it is used (this is, after all, what "_" does in ML). Followup discussion: Dave MacQueen writes: > What you are looking for may be rather difficult to do within the > framework of the ML type system. At first glance it appears to > require a serious innovation in the type system to capture an > abstraction that could instantiate to both "f : 'a -> 'a" and > "f : 'a -> 'b" (note that these two types have different numbers of > bound variables). > > Do you have any suggestions as to how this could be done? I believe it is possible to express type constraints like this with SML: signature S = sig type ('a,'b) from type ('a,'b) to val f : ('a,'b) from -> ('a,'b) to end; structure X:S = struct type ('a,'b) from = 'a type ('a,'b) to = 'a fun f(x) = x end; structure Y:S = struct type ('a,'b) from = 'a * 'b type ('a,'b) to = 'a fun f(x,y) = x end; (These are actually not accepted by NJ/SML 0.70, even if the types for "f" are fully specified in the structure definitions (you get a different error message in that case), but I think that's a bug.) The main problem is that this use of types in signatures seems to have been rather uncommon so far, so, at least NJ/SML has several difficulties with it: * the type checker/module system (incorrectly?) rejects some constructs like this * unused type variables need to be instantiated by the user when they become weak; instead, the language could automatically define such variables to be "unit" * the type constructors "from" and "to" are really auxilliary, and users of S most likely never want to see them printed; the current system prints them * the writer of the signature "S" has to pick a maximum number of auxilliary type variables used as arguments to "from" and "to", but I believe that the actual maximum number needed depends on the arguments given to the functor, not on the functor itself I want to state again that I think this feature is important. Without the ability to specify signatures that can match structures that are polymorphic in different ways, it seems I would have to write completely redundant versions of some functors. The context in which it came up was writing a functor that generates iteration constructs for collections; for some collections, indexes and values are different types, for others, they are the same type. Status: not a bug --------------------------------------------------------------------------- 409. type checking after functor application Submitter: tmb@ai.mit.edu Date: 08/05/91 Version: 0.70 System: Sun4/OS4.1.1 Severity: ? Problem: Basically, I have something like: functor F(...) = struct structure A = G(...); ... open A end; structure X = F(...); X.A.f arg; --> works X.f arg; --> fails with a type error Comment: X.A.f and X.f must refer to the same value with the same type: A has simply been opened at the end of structure X. I don't see how X.f could ever behave differently from X.A.f. Sorry about the long code needed to reproduce the bug. I had several guesses what the problem might be due to, but I have not been able to reduce the code further than this. In particular, the problem goes away if the last functor application is removed, i.e., functor GeneralArray(structure Index:BASICACCESS) = struct ... end; structure Arrays = GeneralArray(structure Index = BasicArrayIndex); is replaced with structure Arrays = struct structure Index:BASICACCESS = BasicArrayIndex ... body of functor GeneralArray ... end Also, don't try to make sense of the code. To isolate the bug this far, I collapsed several types. Code: (file foo.sml) signature BASICACCESS = sig type ('a,'b) index type ('a,'b) range val first: ('a,'b) range -> ('a,'b) index val succ: ('a,'b) index -> ('a,'b) index val done: ('a,'b) index -> bool end; functor GeneralIteration(structure Access:BASICACCESS) = struct local open Access in fun apply f r = let fun loop(i) = if done(i) then () else (f(i); loop(succ(i))) in loop(first(r)) end end end; functor GeneralArray(structure Index:BASICACCESS) = struct type ('a,'b) array = 'b Array.array * ('a,'b) Index.range structure ValueIndex = struct type ('a,'b) range = ('a,'b) array type ('a,'b) index = 'b Array.array * ('a,'b)Index.index fun first((a,r):('a,'b) range) = (a,Index.first(r)) fun succ((a,r):('a,'b) index) = (a,Index.succ(r)) fun done((a,r):('a,'b) index) = Index.done(r) end structure Value = GeneralIteration(structure Access = ValueIndex) fun array(r:(unit,'1b) Index.range,initial):(unit,'1b) array = (Array.array(100,initial),r) open Value end; structure BasicArrayIndex = struct type ('a,'b) index = int * int type ('a,'b) range = int fun first(limit:('a,'b) range):('a,'b) index = (0,limit) fun succ((x,limit):('a,'b) index):('a,'b) index = (x+1,limit) fun done((x,limit):('a,'b) index):bool = x>=limit end; structure Arrays = GeneralArray(structure Index = BasicArrayIndex); Transcript: volterra$ sml Standard ML of New Jersey, Version 0.70, 1 July 1991 val it = () : unit - use "foo.sml"; [opening foo.sml] signature BASICACCESS = sig type ('a,'b) index type ('a,'b) range val done : ('a,'b) index -> bool val first : ('a,'b) range -> ('a,'b) index val succ : ('a,'b) index -> ('a,'b) index end functor GeneralIteration : <sig> functor GeneralArray : <sig> structure BasicArrayIndex : sig eqtype ('a,'b) index eqtype ('a,'b) range val done : ('a,'b) index -> bool val first : ('a,'b) range -> ('a,'b) index val succ : ('a,'b) index -> ('a,'b) index end structure Arrays : sig structure Value : sig...end structure ValueIndex : sig...end eqtype ('a,'b) array val apply : (('a,'b) ?.ValueIndex.index -> 'c) -> ('a,'b) ?.ValueIndex.range -> unit val array : (unit,'1a) BasicArrayIndex.range * '1a -> (unit,'1a) array end [closing foo.sml] val it = () : unit - val x = Arrays.array(100,0); val x = (prim?,100) : (unit,int) Arrays.array - Arrays.Value.Apply (fn a => a) x; std_in:4.1-4.18 Error: unbound variable or constructor in structure: Apply - Arrays.Value.apply (fn a => a) x; val it = () : unit - Arrays.apply (fn a => a) x; std_in:2.1-2.26 Error: operator and operand don't agree (tycon mismatch) operator domain: ('Z,int) ?.ValueIndex.range operand: (unit,int) Arrays.array in expression: Arrays.apply ((fn <pat> => <exp>)) x - volterra$ Status: fixed in 0.73 --------------------------------------------------------------------------- 410. inlining property not preserved in simple renaming Submitter: Andrew Tolmach (apt@cs.princeton.edu) Date: 8/6/91 Version: 0.73 Severity: minor Problem: If I use System.Unsafe.getvar directly, it is inlined, as expected. If I type val g = System.Unsafe.getvar then g does not have access INLINE. Dbm suggests that this is because g is being eta-expanded; I haven't found where this happens in the source. In any case, I don't know why the initial definition of val getvar = InLine.getvar inside the definition of System.Unsafe *does* manage to transfer the inline property... Is it because there's something special about structure InLine? Fix: look for MARKexps around the rhs VALvar. Tolmach: abstract syntax marking. The MARKexps surrounding the RHS of val a = System.Unsafe.getvar prevent the INLINE-ness of getvar being recognized by parse/corelang.sml valbind. If I turn off marking, it works. Tarditi: We should alter parse/corelang.sml valbind so that it recognizes this case specially and properly assigns the INLINE property. Status: fixed in 0.74 --------------------------------------------------------------------------- 411. Runbind Submitter: John Reppy (jhr) Date: 8/10/91 Version: 0.71 Problem: Runbind exception Transcript: Standard ML of New Jersey, Version 0.71, 23 July 1991 val it = () : unit - structure A = struct val x = 1 end; structure A : sig val x : int end - structure B = struct structure A = A; val y = 2 end; structure B : sig structure A : sig...end val y : int end - open A; open A - open B; open B - x; uncaught exception Runbind Status: fixed in 0.73 --------------------------------------------------------------------------- 412. Runbind Submitter: Dave Tarditi Date: 8/13/91 Version: 0.71 Problem: Code: structure A = struct val x = 5 structure B = struct val y = 5 end end open A.B; structure A = struct end; y; Comments: (Tarditi) There's an incorrect assumption in checkopen, which tests whether any value in a structure which has been rebound is still accessible. Let the old structure be called S and the new environment be N. Let the symbols bound in the environment of S be T. The assumption is that if any symbol A in T is unbound in N, then all other symbols in T are also unbound in N. This is clearly untrue, as the above example shows, where x is unbound in the environment after the redefinition of A but y is not. Status: fixed in 0.73 --------------------------------------------------------------------------- 413. System and IO problems Submitter: Emden Gansner Date: 8/16/91 Version: 0.71 Problem: The version of system in the System structure should have type string -> int The execute function in IO is incorrect as written. It passes the the value of environ() to exec, but this is a list of SML strings and exec expects a list of C strings. It should pass (map c_string environ()) instead. Finally, the execute function would be a lot more useful if it allowed a list of arguments as well as program pathname. Status: fixed in 0.74 (JHR) --------------------------------------------------------------------------- 414. getWD wrong Submitter : Ian King <ik@sys.uea.ac.uk> Date : 19th August 1991 Version : SML of New Jersey Version 0.66 , 15 September 1990 System : Sun 3/160 , Sun OS 4.1 Severity : Minor Problem : The function getWD in structure System.Directory when called with a unit gives an incoorect result. Code : fun test path = let val cwd = System.Directory.getWD () in { cd_in = fn () => (cd path), cd_out = fn () => (cd cwd) } end Transcipt : val {cd_in,cd_out} = test "directoryname"; val cd_in = fn : unit -> unit val cd_out = fn : unit -> unit cd_in (); val it = () : unit; cd_out (); uncaught exception NotDirectory Comments : This code executes correctly on a Sun Sparc machine. It does not execute correctly on our Sun 3/160. Although I have marked the bug as minor it is irritating because it crashes code which needs to change directories such as loaders. ** This is probably another example of bug #651 (JHR, 10/6/92) ** Status: fixed --------------------------------------------------------------------------- 415. late error detection in parsing Submitter: David N. Turner <dnt@dcs.ed.ac.uk> Date: 17th September 1991 Version: SML of NJ version 0.73 System: Sun4 Severity: minor Problem: The following incorrect text doesn't generate an error, the secondary prompt appears and the error is only signalled after more text if typed in. Perhaps this is some kind of parser lookahead problem? - if true then 365; (* My input *) = (* nj-sml output *) Status: open --------------------------------------------------------------------------- 416. equality property checking in functor parameter matching Submitter: Simon Finn <simon@abstract-hardware-ltd.co.uk> Date: 9/13/91 Version: ? Severity: minor Problem: Try the following simple (?) exercise in semantics, provided by my colleague Mike Crawley: signature PSIG = sig eqtype 'a symTab ; datatype guide = G1 | G2 of guide symTab end; (Q1) Is guide an eqtype? (in PSIG) (A1) Yes, since we require the equality-principal signature. functor PFUN (structure S : sig type 'a symTab end) = struct open S; datatype guide = G1 | G2 of guide symTab; end; (Q2) Is guide an eqtype? (in the output signature of PFUN) (A2) No, because symTab isn't and our signatures must respect equality structure S = struct datatype 'a symTab = Empty end; structure P = PFUN(structure S = S); (Q3) Is guide an eqtype? (in the signature of P) (A3) No, because it wasn't in the functor. Technically, this is because the realisation, \phi, used to instantiate the body of the functor doesn't touch the bound type names contained in the output signature of the functor (except, possibly, for an alpha-conversion). P.G1 = P.G1; (Q4) Is this legal? (A4) No, because P.guide is not an eqtype (see above). functor MFUN(structure X : PSIG) = struct val z = X.G1 = X.G1; end; structure M = MFUN(structure X = P); (Q5) Is this legal? (A5) No, because MFUN demands that guide be an eqtype (see Q1), but P.guide is not an eqtype (see Q3, Q4). Both SMLNJ 0.66 and Poly/ML 1.88 get Q1 - Q4 right but get Q5 wrong. Poly/ML 1.98 gets Q1 - Q5 right. Comment: Conjecture that this is a benign bug. Have not been able to come up with version that is actually wrong. Fix: Could record equality properties inferred in parameter signature instantiation in the signature (memoizing). Status: open --------------------------------------------------------------------------- 417. cosmetic error message suggestion Submitter: Andy Koenig Date: 9/12/91 Version: ? Problem: Minor suggestion for SML-NJ: in error messages, how about printing infix functions as infix? Transcript: - 3 + 4.0; std_in:1.1-1.7 Error: operator and operand don't agree (tycon mismatch) operator domain: int * int operand: int * real in expression: + (3,4.0) ^^^^^^^^^ Why not 3+4.0 ?? or at least op+ (3,4.0) Comment: use original code in error message instead of "pretty-printing" abstract syntax Status: open --------------------------------------------------------------------------- 418. repeated type names in type declarations Submitter: Andrzej Filinski <andrzej@cs.cmu.edu> Date: September 11, 1991 Version: 0.72 System: All Severity: minor (but with potentially serious consequences) Problem: Repeated type names in DATATYPE ... WITHTYPE ... destroy type security. Transcript: Standard ML of New Jersey, Version 0.72, 29 August 1991 val it = () : unit - datatype t = T of int withtype t = string; datatype t con T : int -> t type t = string - T 65:string; val it = "A" : string - Comments: Same problem with ABSTYPE...WITHTYPE. See also bug report 349. Status: fixed in 0.74 --------------------------------------------------------------------------- 419. Runbind Submitter: Venkatesh Akella akella@cs.utah.edu Date: 8/27/91 Version: SML of NJ version 0.71 System: Sparc IPC, SunOS Severity: major Problem: Raises an uncaught exception Runbind when a simple CML program running under SML version 0.71 (Version of CML being used is 0.95) The bug can't be reproduced with CML version 0.90 running under SML/NJ 0.66 Code: fun placeBuffer () = let val c = channel () val b = channel () val a = channel () fun input_int (s:string) = fold (fn(a,r) => ord(a) - ord("0") + 10 * r) (tl (rev(explode s))) 0; fun P1 x = (CIO.print( "Waiting for Input on Channel a? \n"); let val y = input_int(CIO.input_line std_in) in s__3 x y end) and s__3 x y = ( ( send (c,y ) ; P1 y )) fun P2 z = (let val v = accept c in s__5 z v end) and s__5 z v = ( (CIO.print (" Output on Channel b!"^Integer.makestring(v)^"\n"); P2 v )) in spawn (fn () => P1 4 ); spawn (fn () => P2 5 ); () end; Transcript: 6 bliss /u/akella/compiler/cml/cml95/cml-0.9.5:: > cml val it = true : bool - System.Directory.cd "/u/akella/compiler/hop/example"; val it = () : unit - use "test_buf.sml"; [opening test_buf.sml] [closing test_buf.sml] uncaught exception Runbind - Comments: The same bug was observed in SML/NJ version 0.66 too but in a different context. I had one integrated environment with SML 0.66, ML-yacc, ML-lex, CML(version 0.9) and my own code. Status: fixed in 0.74 --------------------------------------------------------------------------- 420. uncaught Nth while compiling Submitter: Tsung-Min Kuo kuo@ecrc.de Date: Sep 19, 1991 Version: Version 0.66, 15 September 1990 System: SPARCstation 1, SUNOS 4.0 Severity: sever Problem: Compiler-generated exception : uncaught exception Nth Code: signature EXCHANGE_STRUCTURE = sig type tree val new_node : tree -> tree end structure ex : EXCHANGE_STRUCTURE = struct datatype tree = Subwindow of subwindow | Canvas of canvas | Frame of frame | Baseframe of baseframe | NULL withtype subwindow = {t_node: tree} and canvas = {subwindow: subwindow} and frame = {tree_node: tree} and baseframe = {frame: frame,foog:bool} exception Tube_Bug fun position (Canvas c) = position(Subwindow(#subwindow c)) | position (Baseframe bf) = position(Frame (#frame bf)) | position _ = raise Tube_Bug fun tn_set_position(t,p) = () fun set_position (Subwindow sb) = tn_set_position(#t_node sb,0) | set_position (Frame f) = tn_set_position(#tree_node f,0) | set_position (Canvas c) = set_position(Subwindow(#subwindow c)) | set_position (Baseframe bf) = set_position(Frame(#frame bf)) | set_position _ = raise Tube_Bug fun components(Canvas c) = components(Subwindow (#subwindow c)) | components(Baseframe bf) = components(Frame (#frame bf)) | components _ = raise Tube_Bug fun bounding_box(Canvas c) = bounding_box(Subwindow (#subwindow c)) | bounding_box(Baseframe bf) = bounding_box(Frame (#frame bf)) | bounding_box _ = raise Tube_Bug fun tn_set_bounding_box(t,r) = () fun set_bounding_box(Subwindow sb) = tn_set_bounding_box(#t_node sb,0) | set_bounding_box(Frame f) = tn_set_bounding_box(#tree_node f,0) | set_bounding_box(Canvas c) = set_bounding_box(Subwindow(#subwindow c)) | set_bounding_box(Baseframe bf) = set_bounding_box(Frame(#frame bf)) | set_bounding_box _ = raise Tube_Bug fun new_node tl = let val pos = position(Frame {tree_node = tl}) in NULL end end Transcript: - use "bug"; [opening bug] [closing bug] uncaught exception Nth - Comments: The enclosed code is a trimmed version of a big program, got in an attempt to isolate the error. As you can see, this program virtually does nothing and is full of redundancy. But whatever I did to try to cut it down, results in a good program happily accepted by compiler. Here are some of the things I have tried : * not use the signature constraint on the structure * delete any of the redundant function definitions, e.g."components" * remove the redundant call to function "position" in "new_node" * or, even call "position" with argument NULL * remove a clause from any function definition(I tried many of them) * flat the record, e.g. make type frame = tree * remove the boolean field in type "baseframe" * get rid of second argument of functions "tn_set_position" and "tn_set_bounding_box" * replace equal by equal, e.g. replace calls to "tn_set_position" by () * replace recursive call by direct call, e.g. in "Canvas" clause of function "set_position" Conclusion: These are so diverse that I can not even guess any. Status: fixed in 0.73 --------------------------------------------------------------------------- 421. getWD under SPARC/Mach (same as 353) Submitter: Fritz Knabe <Frederick_Knabe@ARCTIC.FOX.CS.CMU.edu> Date: 9/18/91 Version: 0.73 System: SPARC/Mach (CMU) Severity: minor Problem: System.Directory.getWD () is still broken for me in version 73 on a Sparc. It raises a SystemCall exception. Transcript: (c/o Gene Rollins, 8/21/92) Standard ML of New Jersey, Version 0.88, August 14, 1992 with SourceGroup 2.2 built on Mon Aug 17 23:23:16 EDT 1992 - fun pwd() = System.system "pwd"; val pwd = fn : unit -> int - fun cd x = (System.Directory.cd x; pwd()) handle any => (pwd(); raise any); val cd = fn : string -> int - fun ll () = System.system "ls -lL"; val ll = fn : unit -> int - fun mkdir x = System.system ("mkdir " ^ x); val mkdir = fn : string -> int - pwd(); /usr0/rollins val it = 0 : int - ll(); total 0 val it = 0 : int - mkdir "src"; val it = 0 : int - mkdir "bin"; val it = 0 : int - ll(); total 2 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:16 src val it = 0 : int - cd "src"; /usr0/rollins/src val it = 0 : int - cd "../bin"; /usr0/rollins/bin val it = 0 : int - cd "../src"; /usr0/rollins/src val it = 0 : int - cd ".."; /usr0/rollins val it = 0 : int - cd "bin"; /usr0/rollins/bin val it = 0 : int - cd ".."; /usr0/rollins val it = 0 : int - ll(); total 2 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:16 src val it = 0 : int - mkdir "tools"; val it = 0 : int - cd "src"; /usr0/rollins/src val it = 0 : int - cd "../tools"; /usr0/rollins/src uncaught exception NotDirectory - cd "../bin"; /usr0/rollins/bin val it = 0 : int - cd "../tools"; /usr0/rollins/bin uncaught exception NotDirectory (* the rest is more of the same *) - cd ".."; /usr0/rollins val it = 0 : int - cd "tools"; /usr0/rollins/tools val it = 0 : int - cd "../src"; /usr0/rollins/src val it = 0 : int - cd "../tools"; /usr0/rollins/src uncaught exception NotDirectory - cd ".."; /usr0/rollins val it = 0 : int - ll(); total 3 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools val it = 0 : int - mkdir "mo.mipsl"; val it = 0 : int - ll(); total 4 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools val it = 0 : int - cd "mo.mipsl"; /usr0/rollins uncaught exception NotDirectory - cd "src"; /usr0/rollins/src val it = 0 : int - cd "../mo.mipsl"; /usr0/rollins/mo.mipsl val it = 0 : int - cd "../tools"; /usr0/rollins/mo.mipsl uncaught exception NotDirectory - cd "../bin"; /usr0/rollins/bin val it = 0 : int - cd "../mo.mipsl"; /usr0/rollins/mo.mipsl val it = 0 : int - cd ".."; /usr0/rollins val it = 0 : int - cd "mo.mipsl"; /usr0/rollins uncaught exception NotDirectory - ll(); total 4 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools val it = 0 : int - mkdir "zed"; val it = 0 : int - ll(); total 5 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools drwxr-xr-x 2 rollins 512 Aug 20 12:23 zed val it = 0 : int - cd "zed"; /usr0/rollins/zed val it = 0 : int - cd "../tools"; /usr0/rollins/zed uncaught exception NotDirectory - cd "../src"; /usr0/rollins/src val it = 0 : int - cd "../zed"; /usr0/rollins/zed val it = 0 : int - cd ".."; /usr0/rollins val it = 0 : int - mkdir "moon"; val it = 0 : int - cd "moon"; /usr0/rollins uncaught exception NotDirectory - cd "src"; /usr0/rollins/src val it = 0 : int - cd "../moon"; /usr0/rollins/moon val it = 0 : int - cd ".."; /usr0/rollins val it = 0 : int - ll(); total 6 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:24 moon drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools drwxr-xr-x 2 rollins 512 Aug 20 12:23 zed val it = 0 : int - mkdir "tooth"; val it = 0 : int - ll(); total 7 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:24 moon drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools drwxr-xr-x 2 rollins 512 Aug 20 12:25 tooth drwxr-xr-x 2 rollins 512 Aug 20 12:23 zed val it = 0 : int - cd "tooth"; /usr0/rollins/tooth val it = 0 : int - cd "../src"; /usr0/rollins/src val it = 0 : int - cd "../tooth"; /usr0/rollins/src uncaught exception NotDirectory - cd ".."; /usr0/rollins val it = 0 : int - ll(); total 7 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:24 moon drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools drwxr-xr-x 2 rollins 512 Aug 20 12:25 tooth drwxr-xr-x 2 rollins 512 Aug 20 12:23 zed val it = 0 : int - cd "mzz"; /usr0/rollins uncaught exception NotDirectory - mkdir "mzz"; val it = 0 : int - cd "mzz"; /usr0/rollins/mzz val it = 0 : int - cd "../src"; /usr0/rollins/src val it = 0 : int - cd "../mzz"; /usr0/rollins/mzz val it = 0 : int - mkdir "me"; val it = 0 : int - ll(); total 1 drwxr-xr-x 2 rollins 512 Aug 20 12:26 me val it = 0 : int - pwd(); /usr0/rollins/mzz val it = 0 : int - cd ".."; /usr0/rollins val it = 0 : int - mkdir "me"; val it = 0 : int - ll(); total 9 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:26 me drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:24 moon drwxr-xr-x 3 rollins 512 Aug 20 12:26 mzz drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools drwxr-xr-x 2 rollins 512 Aug 20 12:25 tooth drwxr-xr-x 2 rollins 512 Aug 20 12:23 zed val it = 0 : int - cd "me"; /usr0/rollins/me val it = 0 : int - cd "../tooth"; /usr0/rollins/me uncaught exception NotDirectory - cd ".."; /usr0/rollins val it = 0 : int - mkdir "teeth"; val it = 0 : int - cd "teeth"; /usr0/rollins/teeth val it = 0 : int - cd "../src"; /usr0/rollins/src val it = 0 : int - cd "../teeth"; /usr0/rollins/src uncaught exception NotDirectory - cd ".."; /usr0/rollins val it = 0 : int - ll(); total 10 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:26 me drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:24 moon drwxr-xr-x 3 rollins 512 Aug 20 12:26 mzz drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:27 teeth drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools drwxr-xr-x 2 rollins 512 Aug 20 12:25 tooth drwxr-xr-x 2 rollins 512 Aug 20 12:23 zed val it = 0 : int - mkdir "tzz"; val it = 0 : int - ll(); total 11 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:26 me drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:24 moon drwxr-xr-x 3 rollins 512 Aug 20 12:26 mzz drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:27 teeth drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools drwxr-xr-x 2 rollins 512 Aug 20 12:25 tooth drwxr-xr-x 2 rollins 512 Aug 20 12:27 tzz drwxr-xr-x 2 rollins 512 Aug 20 12:23 zed val it = 0 : int - cd "tzz"; /usr0/rollins/tzz val it = 0 : int - cd "../src"; /usr0/rollins/src val it = 0 : int - cd "../tzz"; /usr0/rollins/tzz val it = 0 : int - cd "../teeth"; /usr0/rollins/tzz uncaught exception NotDirectory - cd ".."; /usr0/rollins val it = 0 : int - ll(); total 11 drwxr-xr-x 2 rollins 512 Aug 20 12:16 bin drwxr-xr-x 2 rollins 512 Aug 20 12:26 me drwxr-xr-x 2 rollins 512 Aug 20 12:18 mo.mipsl drwxr-xr-x 2 rollins 512 Aug 20 12:24 moon drwxr-xr-x 3 rollins 512 Aug 20 12:26 mzz drwxr-xr-x 2 rollins 512 Aug 20 12:16 src drwxr-xr-x 2 rollins 512 Aug 20 12:27 teeth drwxr-xr-x 2 rollins 512 Aug 20 12:17 tools drwxr-xr-x 2 rollins 512 Aug 20 12:25 tooth drwxr-xr-x 2 rollins 512 Aug 20 12:27 tzz drwxr-xr-x 2 rollins 512 Aug 20 12:23 zed val it = 0 : int - Comment: (Lal George) There is an operating system level 3 call that can be used to get the working directory. Unfortunately, we cannot use this because it does a malloc. So we have to build up the working directory pathname by interpreting inodes. It is my guess that this is what bombs out in the Andrew file system. ** This is probably another example of bug #651 (JHR, 10/6/92) ** Status: fixed --------------------------------------------------------------------------- 422. overflow on int to real conversion Submitter: Andrzej Filinski <andrzej@cs.cmu.edu> Date: September 20, 1991 Version: 0.73 System: all Severity: major Problem: int->real conversion overflows on MININT Transcript: Standard ML of New Jersey, Version 0.73, 10 September 1991 Arrays have changed; see doc/NEWS val it = () : unit - ~0x40000000; val it = ~1073741824 : int - real it; uncaught exception Overflow - Fix: In boot/perv.sml, move redundant check for MININT from Integer.mod to Real.real :-). Status: Fixed in 0.74 --------------------------------------------------------------------------- 423. printing of structure signatures Submitter: John Reppy Date: 10/1/91 Version: 0.73 Severity: minor Problem: At top level, some structure signatures are printed as identifiers, while others are printed in full. Transcript: Standard ML of New Jersey, Version 0.73, 10 September 1991 Arrays have changed; see doc/NEWS val it = () : unit - structure I = IO; structure I : IO - structure V = Vector; structure V : sig eqtype 'a vector exception Size exception Subscript val length : 'a vector -> int val sub : 'a vector * int -> 'a val tabulate : int * (int -> 'a) -> 'a vector val vector : 'a list -> 'a vector val vector_n : int * 'a list -> 'a vector end - Comments: [Dave Tarditi] The reported behavior is intentional: the basic idea is that if we know the name of a structure's signature, we print the name of the signature instead of the whole signature. More formally, if S is structure which is bound to structure id SX, and S was the result of doing a signature match against signature T, which itself is bound to signature identifier TX, then when we print the signature for the structure bound to SX, we will print TX, provided that TX is still bound to the same signature. Thus we get the following results at the top-level: - structure S = IO; structure S : IO - structure T = S; structure T : IO but when we re-bind the signature identifier IO we get: - signature IO = sig end; signature IO = sig end - structure S = IO structure S = sig type instream ... end The problem is that the signature identifier VECTOR is not in the top-level environment. To fix this, change build/process.sml, lines 202-204 from: map Symbol.sigSymbol ["REF","LIST","ARRAY","BYTEARRAY","IO","BOOL", "ENVIRON", "COMPILE", "STRING","INTEGER","REAL","GENERAL"] to: map Symbol.sigSymbol ["REF","LIST","ARRAY","BYTEARRAY","IO","BOOL", "ENVIRON", "COMPILE" "STRING","INTEGER","REAL","GENERAL", "VECTOR"] Maybe we should add a flag to toggle this behavior, but I was hoping that we would an environment browsing structure to the compiler instead. It's a kludge to have to type "structure S = S" to see the signature of S. Status: not a but (but a feature!) --------------------------------------------------------------------------- 424. IO.execute on SPARC Submitter: Emden Gansner Date: 10/1/91 Version: 0.73 System: SPARC, SunOS 4.1 Severity: moderate Problem: "I just noticed that, starting with 0.71, the IO.execute function causes problems on the sparc, running SunOS4.1. This problem doesn't occur on 0.73 running on hunny." Transcript: t) /usr/addon/sml/bin/*69* Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - IO.execute "/bin/date"; val it = (-,-) : instream * outstream - t) t) sml Standard ML of New Jersey, Version 0.71, 23 July 1991 val it = () : unit - IO.execute "/bin/date"; /home/erg/bin/sml[7]: 6446 Bus error t) sml73 Standard ML of New Jersey, Version 0.73, 10 September 1991 val it = () : unit - IO.execute "/bin/date"; Bus error t) Status: fixed in 0.74 (JHR) --------------------------------------------------------------------------- 425. profiler flakiness Submitter: Frank Pfenning Date: 10/2/91 Version: 0.73 Problem: I am currently in the process of eliminating obvious inefficiencies in an ML implementation of a logic programming language. While using the profiler, I noticed that it seemed to lead to inordinately large core images during the development (there is also a small overhead for the mere fact that we are profiling, but that is acceptable). My guess is the profiler keeps a (non-weak) pointer to code somehow, which prevents it from being garbage collected even if it is no longer accessible from the top-level. The fact that redefined functions show up twice or more often in the profiling statistics seem to confirm that, but I may be using it wrong, or there could be other reasons. I would be interested to hear what the developer/implementor of the profiler has to say about this. Thanks, Comment: (Andrew Appel) Yes, I think your analysis is correct. There's a profiler function that resets the profiler; perhaps that's what you want. But if you use it, you'd have to reload your entire source code. Status: fixed in 0.86 --------------------------------------------------------------------------- 426. type printing Submitter: Andy Koenig (europa!ark) Date: 10/4/91 Version: 0.73 Severity: minor Problem: Spurious parenthesis around unit. Transcript: - (3,()); val it = (3,()) : int * (unit) Status: fixed in 0.74 --------------------------------------------------------------------------- 427. Compiler bug: defineEqTycon/eqtyc Submitter: John Reppy Date: 10/6/91 Version: 0.73 Severity: ? Problem: Compiler bug: defineEqTycon/eqtyc -- bad tycon Transcript: Standard ML of New Jersey, Version 0.73, 10 September 1991 Arrays have changed; see doc/NEWS val it = () : unit - datatype 'a array = ARRAY of 'a ref VECTOR; std_in:2.38-2.43 Error: unbound type constructor VECTOR Error: Compiler bug: defineEqTycon/eqtyc -- bad tycon Comments: Obviously this code is incorrect, but I have a bigger example that only prints out the "bad tycon" message. Status: fixed in 0.74 --------------------------------------------------------------------------- 428. openStructureVar -- bad access value Submitter: Benjamin.Pierce@cs.cmu.edu Date: 4/3/91 Version: 0.67 (with SourceGroup) System: SunOS 4.1 Severity: Major Problem: Compiler bug: EnvAccess.openStructureVar -- bad access value Code: see below Transcript: Standard ML of New Jersey, Version 0.67, 21 November 1990 (Built on Sun Mar 17 11:37:30 EST 1991 with GnuTags and SourceGroup) val it = () : unit - use "bad.tmp"; [opening bad.tmp] signature WR = sig type Wr val close : Wr -> unit val extract_str : Wr -> string val to_file : string -> Wr val to_fn : (string -> unit) -> (unit -> unit) -> Wr val to_nowhere : unit -> Wr val to_stdout : unit -> Wr val to_string : unit -> Wr val to_wrs : Wr list -> Wr val write_wr : Wr -> string -> unit end signature PP = sig structure Wr : sig...end type Pp val DEBUG : bool ref val break : Pp -> bool -> int -> unit val endb : Pp -> unit val expbreak : Pp -> bool -> string -> unit val pp_from_wr : Wr.Wr -> Pp val pwrite : Pp -> string -> unit val set_margin : Pp -> int -> unit val setb : Pp -> unit val wr_from_pp : Pp -> Wr.Wr end signature WRMGT = sig structure Pp : sig...end structure Wr : sig...end val get_current_wr : unit -> Wr.Wr val set_current_wr : Wr.Wr -> unit val stdpp : unit -> Pp.Pp val write : string -> unit end signature STRINGUTILS = sig end signature REGISTRY = sig type registeredtype val register : string -> (registeredtype -> unit) -> unit val registerflag : string -> registeredtype ref -> unit val set_all : registeredtype -> unit val set_flag : string -> registeredtype -> unit end signature LISTUTILS = sig val filter : ('a -> bool) -> 'a list -> 'a list val forall : ('a -> bool) -> 'a list -> bool val forsome : ('a -> bool) -> 'a list -> bool val mapappend : ('a -> 'b list) -> 'a list -> 'b list val mapfold : ('a -> 'b) -> ('b -> 'b -> 'b) -> 'b -> 'a list -> 'b val mapunit : ('b -> 'a) -> 'b list -> unit val mapunit_tuple : ('a -> unit) -> (unit -> unit) -> 'a list -> unit val memq : ('a -> 'a -> bool) -> 'a list -> 'a -> bool end signature ID = sig type T val == : T -> T -> bool val hashcode : T -> int val intern : string -> T val new : unit -> T val new_from : T -> T val tostr : T -> string end signature DEBUGUTILS = sig val wrap : bool ref -> string -> (unit -> 'a) -> (unit -> unit) -> ('a -> unit) -> 'a end signature GLOBALS = sig structure Id : sig...end structure Pp : sig...end structure Pp : sig...end structure Wr : sig...end structure Wr : sig...end structure WrMgt : sig...end type registeredtype val filter : ('a -> bool) -> 'a list -> 'a list val forall : ('a -> bool) -> 'a list -> bool val forsome : ('a -> bool) -> 'a list -> bool val get_current_wr : unit -> Wr.Wr val mapappend : ('a -> 'b list) -> 'a list -> 'b list val mapfold : ('a -> 'b) -> ('b -> 'b -> 'b) -> 'b -> 'a list -> 'b val mapunit : ('b -> 'a) -> 'b list -> unit val mapunit_tuple : ('a -> unit) -> (unit -> unit) -> 'a list -> unit val memq : ('a -> 'a -> bool) -> 'a list -> 'a -> bool val register : string -> (registeredtype -> unit) -> unit val registerflag : string -> registeredtype ref -> unit val set_all : registeredtype -> unit val set_current_wr : Wr.Wr -> unit val set_flag : string -> registeredtype -> unit val stdpp : unit -> Pp.Pp val wrap : bool ref -> string -> (unit -> 'a) -> (unit -> unit) -> ('a -> unit) -> 'a val write : string -> unit end Error: Compiler bug: EnvAccess.openStructureVar -- bad access value [closing bad.tmp] - -------------------------------------------------------------------------- (* And here's the offending file ... *) signature WR = sig type Wr val to_stdout: unit -> Wr val to_file: string -> Wr val to_nowhere: unit -> Wr val to_wrs: Wr list -> Wr val to_fn: (string->unit) -> (unit->unit) -> Wr val to_string: unit -> Wr val extract_str: Wr -> string val close: Wr -> unit val write_wr: Wr -> string -> unit end; signature PP = sig structure Wr: WR type Pp val pp_from_wr: Wr.Wr -> Pp val wr_from_pp: Pp -> Wr.Wr; val pwrite : Pp -> string -> unit val setb: Pp -> unit val endb: Pp -> unit val break: Pp -> bool -> int -> unit val expbreak: Pp -> bool -> string -> unit val set_margin: Pp -> int -> unit val DEBUG: bool ref end; signature WRMGT = sig (* Maintains a notion of a current (prettyprinting) writer and its associated prettyprinter *) structure Wr: WR; structure Pp: PP; sharing Pp.Wr = Wr; val set_current_wr: Wr.Wr -> unit; val get_current_wr: unit -> Wr.Wr; val stdpp: unit -> Pp.Pp; val write: string -> unit; end; signature STRINGUTILS = sig end; signature REGISTRY = sig type registeredtype val register: string -> (registeredtype->unit) -> unit val registerflag: string -> (registeredtype ref) -> unit val set_flag: string -> registeredtype -> unit val set_all: registeredtype -> unit end; signature LISTUTILS = sig val memq: ('a -> 'a -> bool) -> 'a list -> 'a -> bool val mapappend: ('a -> 'b list) -> ('a list) -> ('b list) val mapunit: ('a -> 'b) -> ('a list) -> unit val mapunit_tuple: ('a -> unit) -> (unit -> unit) -> ('a list) -> unit val mapfold: ('a -> 'b) -> ('b -> 'b -> 'b) -> 'b -> ('a list) -> 'b val forall: ('a -> bool) -> ('a list) -> bool val forsome: ('a -> bool) -> ('a list) -> bool val filter: ('a -> bool) -> ('a list) -> ('a list) end; signature ID = sig type T val intern: string -> T val tostr: T -> string val hashcode: T -> int val new: unit -> T val new_from: T -> T val == : T -> T -> bool end; (* May eventually want to support these too: val lexlt : T -> T -> bool *) signature DEBUGUTILS = sig val wrap: (bool ref) -> string -> (unit -> 'a) -> (unit -> unit) -> ('a -> unit) -> 'a end; signature GLOBALS = sig structure Wr: WR structure Pp: PP structure WrMgt: WRMGT structure Id: ID sharing Pp.Wr = Wr sharing WrMgt.Pp = Pp include WRMGT include LISTUTILS include STRINGUTILS include DEBUGUTILS include REGISTRY sharing type registeredtype = bool end; signature TYPPVT = sig structure Globals: GLOBALS open Globals datatype pretyp = PRETVAR of Id.T | PREARROW of pretyp * pretyp | PREALL of Id.T * pretyp * pretyp | PREMEET of pretyp list datatype T = TVAR of unit * int | ARROW of unit * T * T | ALL of {name:Id.T} * T * T | MEET of unit * (T list) datatype tenvelt = BND of Id.T * T | ABB of Id.T * T | VBND of Id.T * T datatype tenv = TENV of tenvelt list val empty_tenv: tenv val extend_bound: tenv -> Id.T -> T -> tenv val push_bound: tenv -> Id.T -> T -> tenv val extend_abbrev: tenv -> Id.T -> T -> tenv val push_abbrev: tenv -> Id.T -> T -> tenv val extend_binding: tenv -> Id.T -> T -> tenv val push_binding: tenv -> Id.T -> T -> tenv val pop: tenv -> tenv val index: tenv -> Id.T -> int val lookup_name: tenv -> int -> Id.T val lookup_and_relocate_bound: tenv -> int -> T val lookup_and_relocate_binding: tenv -> int -> T val lookup_and_relocate: tenv -> int -> tenvelt val lookup: tenv -> int -> tenvelt val relocate: int -> T -> T exception UnknownId of string exception WrongKindOfId of tenv * int * string val debruijnify: tenv -> pretyp -> T val prt: Pp.Pp -> tenv -> T -> unit val prt_tenv: Pp.Pp -> tenv -> unit val NS: T end; Status: fixed in 0.71 --------------------------------------------------------------------------- 429. signature match fails Submitter: Benjamin Pierce <Benjamin.Pierce@PROOF.ERGO.CS.CMU.EDU> Date: 4/4/91 Version: 0.69 Problem: signature spec not matched when it should be Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "bug.tmp"; use "bug.tmp"; [opening bug.tmp] [Major collection... [Increasing heap to 10011k] 96% used (3502604/3627780), 7260 msec] [Increasing heap to 10431k] bug.tmp:1545.8-1775.3 Error: value type in structure doesn't match signature spec name: prt spec: Pp -> tenv -> T -> unit actual: ?.Pp -> tenv -> T -> unit bug.tmp:1545.8-1775.3 Error: value type in structure doesn't match signature spec name: prt_tenv spec: Pp -> tenv -> unit actual: ?.Pp -> tenv -> unit bug.tmp:1798.7-1802.44 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: Typ.prt pp bug.tmp:1798.7-1820.56 Error: rules don't agree (tycon mismatch) expected: ?.Pp * 'Z * 'Y list * 'X * rhs_flag -> unit found: ?.Pp * tenv * lhsqueue list * 'W * 'V -> 'U rule: (pp,te,:: (ARROW_LHS <pat>,nil),t2,flag) => (<exp> <exp> te t1;# # t2 flag) bug.tmp:1807.7-1809.38 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: Pp.pwrite pp bug.tmp:1798.7-1820.56 Error: rules don't agree (tycon mismatch) expected: ?.Pp * 'Z * 'Y list * 'X * rhs_flag -> unit found: ?.Pp * tenv * lhsqueue list * 'W * 'V -> 'U rule: (pp,te,:: (ARROW_LHS <pat>,X2),t2,flag) => (<exp> <exp> te t1;Pp.pwrite pp ",";# # t2 flag) bug.tmp:1811.7-1814.56 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: Typ.prt pp bug.tmp:1811.7-1814.56 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: describe_rest pp bug.tmp:1816.7-1820.56 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: Typ.prt pp bug.tmp:1816.7-1820.56 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: describe_rest pp bug.tmp:1797.1-1820.56 Error: pattern and expression in val rec dec don't agree (tycon mismatch) pattern: ?.Pp -> tenv -> lhsqueue list -> 'Z -> 'Y -> 'X expression: ?.Pp -> tenv -> lhsqueue list -> 'W -> rhs_flag -> unit in declaration: describe_rest = (fn arg => (fn <pat> => <exp>)) bug.tmp:1823.3-1829.14 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: Typ.prt pp bug.tmp:1823.3-1829.14 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: describe_rest pp bug.tmp:1874.15-1874.54 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.Pp operand: ?.Pp in expression: describe_problem (stdpp ()) [closing bug.tmp] -------------------------------------------------------------------------- (* and here's the offending file... Sorry it's a bit long *) signature WR = sig type Wr val to_stdout: unit -> Wr val to_file: string -> Wr val to_nowhere: unit -> Wr val to_wrs: Wr list -> Wr val to_fn: (string->unit) -> (unit->unit) -> Wr val to_string: unit -> Wr val extract_str: Wr -> string val close: Wr -> unit val write_wr: Wr -> string -> unit end signature PP = sig structure Wr: WR type Pp val pp_from_wr: Wr.Wr -> Pp val wr_from_pp: Pp -> Wr.Wr; val pwrite : Pp -> string -> unit val setb: Pp -> unit val endb: Pp -> unit val break: Pp -> bool -> int -> unit val expbreak: Pp -> bool -> string -> unit val set_margin: Pp -> int -> unit val DEBUG: bool ref end signature WRMGT = sig (* Maintains a notion of a current (prettyprinting) writer and its associated prettyprinter *) structure Wr: WR; structure Pp: PP; sharing Pp.Wr = Wr; val set_current_wr: Wr.Wr -> unit; val get_current_wr: unit -> Wr.Wr; val stdpp: unit -> Pp.Pp; val write: string -> unit; end signature STRINGUTILS = sig end signature REGISTRY = sig type registeredtype val register: string -> (registeredtype->unit) -> unit val registerflag: string -> (registeredtype ref) -> unit val set_flag: string -> registeredtype -> unit val set_all: registeredtype -> unit end signature LISTUTILS = sig val memq: ('a -> 'a -> bool) -> 'a list -> 'a -> bool val mapappend: ('a -> 'b list) -> ('a list) -> ('b list) val mapunit: ('a -> 'b) -> ('a list) -> unit val mapunit_tuple: ('a -> unit) -> (unit -> unit) -> ('a list) -> unit val mapfold: ('a -> 'b) -> ('b -> 'b -> 'b) -> 'b -> ('a list) -> 'b val forall: ('a -> bool) -> ('a list) -> bool val forsome: ('a -> bool) -> ('a list) -> bool val filter: ('a -> bool) -> ('a list) -> ('a list) end signature ID = sig type T val intern: string -> T val tostr: T -> string val hashcode: T -> int val new: unit -> T val new_from: T -> T val == : T -> T -> bool end (* May eventually want to support these too: val lexlt : T -> T -> bool *) signature DEBUGUTILS = sig val wrap: (bool ref) -> string -> (unit -> 'a) -> (unit -> unit) -> ('a -> unit) -> 'a end signature GLOBALS = sig structure Wr: WR structure Pp: PP structure WrMgt: WRMGT structure Id: ID sharing Pp.Wr = Wr sharing WrMgt.Pp = Pp include WRMGT include LISTUTILS include STRINGUTILS include DEBUGUTILS include REGISTRY sharing type registeredtype = bool exception CantHappen end signature TYPPVT = sig structure Globals: GLOBALS open Globals datatype pretyp = PRETVAR of Id.T | PREARROW of pretyp * pretyp | PREALL of Id.T * pretyp * pretyp | PREMEET of pretyp list datatype T = TVAR of unit * int | ARROW of unit * T * T | ALL of {name:Id.T} * T * T | MEET of unit * (T list) datatype tenvelt = BND of Id.T * T | ABB of Id.T * T | VBND of Id.T * T datatype tenv = TENV of tenvelt list val empty_tenv: tenv val push_bound: tenv -> Id.T -> T -> tenv val push_abbrev: tenv -> Id.T -> T -> tenv val push_binding: tenv -> Id.T -> T -> tenv val pop: tenv -> tenv val index: tenv -> Id.T -> int val lookup_name: tenv -> int -> Id.T val lookup_and_relocate_bound: tenv -> int -> T val lookup_and_relocate_binding: tenv -> int -> T val lookup_and_relocate: tenv -> int -> tenvelt val lookup: tenv -> int -> tenvelt val relocate: int -> T -> T (* Substitute the first arg for instances of var #0 in the second arg *) val tsubst_top: T -> T -> T exception UnknownId of string exception WrongKindOfId of tenv * int * string val debruijnify: tenv -> pretyp -> T val prt: Pp.Pp -> tenv -> T -> unit val prt_tenv: Pp.Pp -> tenv -> unit val NS: T end signature LEQ = sig structure Typ: TYPPVT structure Globals: GLOBALS sharing Globals = Typ.Globals val leq: Typ.tenv -> Typ.T -> Typ.T -> bool end (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) (* LR_TABLE: signature for an LR Table. The list of actions and gotos passed to mkLrTable must be ordered by state number. The values for state 0 are the first in the list, the values for state 1 are next, etc. *) signature LR_TABLE = sig datatype state = STATE of int datatype term = T of int datatype nonterm = NT of int datatype action = SHIFT of state | REDUCE of int | ACCEPT | ERROR type table val numStates : table -> int val describeActions : table -> state -> ((term * action) list) * action val describeGoto : table -> state -> (nonterm * state) list val action : table -> state * term -> action val goto : table -> state * nonterm -> state val initialState : table -> state exception Goto of state * nonterm val mkLrTable : {actions : (((term * action) list) * action) list, gotos : (nonterm * state) list list, numStates : int, initialState : state} -> table end (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) (* import "lr_table.sig"; *) (* TOKEN: signature revealing the internal structure of a token. This signature TOKEN distinct from the signature {parser name}_TOKENS produced by ML-Yacc. The {parser name}_TOKENS structures contain some types and functions to construct tokens from values and positions. The representation of token was very carefully chosen here to allow the polymorphic parser to work without knowing the types of semantic values or line numbers. This has had an impact on the TOKENS structure produced by SML-Yacc, which is a structure parameter to lexer functors. We would like to have some type 'a token which functions to construct tokens would create. A constructor function for a integer token might be INT: int * 'a * 'a -> 'a token. This is not possible because we need to have tokens with the representation given below for the polymorphic parser. Thus our constructur functions for tokens have the form: INT: int * 'a * 'a -> (svalue,'a) token This in turn has had an impact on the signature that lexers for SML-Yacc must match and the types that a user must declare in the user declarations section of lexers. *) signature TOKEN = sig structure LrTable : LR_TABLE datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b) val sameToken : ('a,'b) token * ('a,'b) token -> bool end (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) (* import "lr_table.sig"; import "token.sig"; *) (* PARSER_DATA: the signature of ParserData structures in {parser name}LrValsFun produced by SML-Yacc. All such structures match this signature. The {parser name}LrValsFun produces a structure which contains all the values except for the lexer needed to call the polymorphic parser mentioned before. *) signature PARSER_DATA = sig (* the type of line numbers *) type pos (* the type of semantic values *) type svalue (* the type of the user-supplied argument to the parser *) type arg (* the intended type of the result of the parser. This value is produced by applying extract from the structure Actions to the final semantic value resultiing from a parse. *) type result structure LrTable : LR_TABLE structure Token : TOKEN sharing Token.LrTable = LrTable (* structure Actions contains the functions which mantain the semantic values stack in the parser. Void is used to provide a default value for the semantic stack. *) structure Actions : sig val actions : int * pos * (LrTable.state * (svalue * pos * pos)) list * arg-> LrTable.nonterm * (svalue * pos * pos) * ((LrTable.state *(svalue * pos * pos)) list) val void : svalue val extract : svalue -> result end (* structure EC contains information used to improve error recovery in an error-correcting parser *) structure EC : sig val is_keyword : LrTable.term -> bool val noShift : LrTable.term -> bool val preferred_subst : LrTable.term -> LrTable.term list val preferred_insert : LrTable.term -> bool val errtermvalue : LrTable.term -> svalue val showTerminal : LrTable.term -> string val terms: LrTable.term list end (* table is the LR table for the parser *) val table : LrTable.table end signature FMEET_TOKENS = sig type ('a,'b) token type svalue val T_PACK: ('a * 'a) ->(svalue,'a) token val T_END: ('a * 'a) ->(svalue,'a) token val T_OPEN: ('a * 'a) ->(svalue,'a) token val T_SOME: ('a * 'a) ->(svalue,'a) token val T_INSTALL: ('a * 'a) ->(svalue,'a) token val T_OBSERVE: ('a * 'a) ->(svalue,'a) token val T_FOR: ('a * 'a) ->(svalue,'a) token val T_OF: ('a * 'a) ->(svalue,'a) token val T_CASE: ('a * 'a) ->(svalue,'a) token val T_NS: ('a * 'a) ->(svalue,'a) token val T_IN: ('a * 'a) ->(svalue,'a) token val T_ALL: ('a * 'a) ->(svalue,'a) token val T_WITH: ('a * 'a) ->(svalue,'a) token val T_CHECK: ('a * 'a) ->(svalue,'a) token val T_DEBUG: ('a * 'a) ->(svalue,'a) token val T_RESET: ('a * 'a) ->(svalue,'a) token val T_SET: ('a * 'a) ->(svalue,'a) token val T_TYPE: ('a * 'a) ->(svalue,'a) token val T_USE: ('a * 'a) ->(svalue,'a) token val T_STR_CONST: ((string) * 'a * 'a) ->(svalue,'a) token val T_INT_CONST: ((string) * 'a * 'a) ->(svalue,'a) token val T_ID: ((string) * 'a * 'a) ->(svalue,'a) token val T_BIGLAMBDA: ('a * 'a) ->(svalue,'a) token val T_LAMBDA: ('a * 'a) ->(svalue,'a) token val T_INTER: ('a * 'a) ->(svalue,'a) token val T_RCURLY: ('a * 'a) ->(svalue,'a) token val T_LCURLY: ('a * 'a) ->(svalue,'a) token val T_RANGLE: ('a * 'a) ->(svalue,'a) token val T_LANGLE: ('a * 'a) ->(svalue,'a) token val T_RBRACK: ('a * 'a) ->(svalue,'a) token val T_LBRACK: ('a * 'a) ->(svalue,'a) token val T_RPAREN: ('a * 'a) ->(svalue,'a) token val T_LPAREN: ('a * 'a) ->(svalue,'a) token val T_DARROW: ('a * 'a) ->(svalue,'a) token val T_ARROW: ('a * 'a) ->(svalue,'a) token val T_AT: ('a * 'a) ->(svalue,'a) token val T_DOLLAR: ('a * 'a) ->(svalue,'a) token val T_DOUBLEEQ: ('a * 'a) ->(svalue,'a) token val T_EQ: ('a * 'a) ->(svalue,'a) token val T_APOST: ('a * 'a) ->(svalue,'a) token val T_COMMA: ('a * 'a) ->(svalue,'a) token val T_LEQ: ('a * 'a) ->(svalue,'a) token val T_SEMICOLON: ('a * 'a) ->(svalue,'a) token val T_COLON: ('a * 'a) ->(svalue,'a) token val T_DOT: ('a * 'a) ->(svalue,'a) token val T_EOF: ('a * 'a) ->(svalue,'a) token end signature FMEET_LRVALS = sig structure Tokens : FMEET_TOKENS structure ParserData:PARSER_DATA sharing type ParserData.Token.token = Tokens.token sharing type ParserData.svalue = Tokens.svalue end (* Externally visible aspects of the lexer and parser *) signature INTERFACE = sig type pos val line : pos ref val init_line : unit -> unit val next_line : unit -> unit val error : string * pos * pos -> unit end (* signature INTERFACE *) signature TYP = sig structure Globals: GLOBALS open Globals datatype pretyp = PRETVAR of Id.T | PREARROW of pretyp * pretyp | PREALL of Id.T * pretyp * pretyp | PREMEET of pretyp list type T type tenv val empty_tenv: tenv val push_bound: tenv -> Id.T -> T -> tenv val push_abbrev: tenv -> Id.T -> T -> tenv val push_binding: tenv -> Id.T -> T -> tenv val pop: tenv -> tenv exception UnknownId of string exception WrongKindOfId of tenv * int * string val debruijnify: tenv -> pretyp -> T val prt: Pp.Pp -> tenv -> T -> unit val prt_tenv: Pp.Pp -> tenv -> unit val NS: T end signature TRM = sig structure Globals: GLOBALS structure Typ: TYP sharing Typ.Globals = Globals open Globals datatype pretrm = PREVAR of Id.T | PREABS of Id.T * Typ.pretyp * pretrm | PREAPP of pretrm * pretrm | PRETABS of Id.T * Typ.pretyp * pretrm | PRETAPP of pretrm * Typ.pretyp | PREFOR of Id.T * (Typ.pretyp list) * pretrm type T exception UnknownId of string val debruijnify: Typ.tenv -> pretrm -> T val prt: Pp.Pp -> Typ.tenv -> T -> unit end signature PARSERES = sig structure Typ : TYP structure Trm : TRM structure Globals: GLOBALS sharing Typ.Globals = Globals sharing Trm.Typ = Typ datatype T = Leq of Typ.pretyp * Typ.pretyp | Type_Assumption of Globals.Id.T * Typ.pretyp | Type_Abbrev of Globals.Id.T * Typ.pretyp | Term_Def of Globals.Id.T * Trm.pretrm | Term_Assumption of Globals.Id.T * Typ.pretyp | Use of string | Set of string * string | Nothing end signature PARSE = sig structure ParseRes : PARSERES val file_parse: string -> ParseRes.T; val stream_parse: instream -> ParseRes.T; val top_parse: unit -> ParseRes.T; end (* signature PARSE *) (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) (* STREAM: signature for a lazy stream.*) signature STREAM = sig type 'xa stream val streamify : (unit -> '_a) -> '_a stream val cons : '_a * '_a stream -> '_a stream val get : '_a stream -> '_a * '_a stream end (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) (* import "token.sig"; import "stream.sig"; *) (* signature PARSER is the signature that most user parsers created by SML-Yacc will match. *) signature PARSER = sig structure Token : TOKEN structure Stream : STREAM exception ParseError (* type pos is the type of line numbers *) type pos (* type result is the type of the result from the parser *) type result (* the type of the user-supplied argument to the parser *) type arg (* type svalue is the type of semantic values for the semantic value stack *) type svalue (* val makeLexer is used to create a stream of tokens for the parser *) val makeLexer : (int -> string) -> (svalue,pos) Token.token Stream.stream (* val parse takes a stream of tokens and a function to prt errors and returns a value of type result and a stream containing the unused tokens *) val parse : int * ((svalue,pos) Token.token Stream.stream) * (string * pos * pos -> unit) * arg -> result * (svalue,pos) Token.token Stream.stream val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> bool end functor Parse (structure Globals : GLOBALS structure ParseRes : PARSERES structure Interface : INTERFACE structure Parser : PARSER sharing type Parser.pos = Interface.pos sharing type Parser.result = ParseRes.T sharing type Parser.arg = unit structure Tokens : FMEET_TOKENS sharing type Tokens.token = Parser.Token.token sharing type Tokens.svalue = Parser.svalue ) : PARSE = struct structure ParseRes = ParseRes open Globals val parse = fn (lookahead,reader : int -> string) => let val _ = Interface.init_line() val empty = !Interface.line val dummyEOF = Tokens.T_EOF(empty,empty) fun invoke lexer = Parser.parse(lookahead,lexer,Interface.error,()) fun loop lexer = let val (result,lexer) = invoke lexer val (nextToken,lexer) = Parser.Stream.get lexer in if Parser.sameToken(nextToken,dummyEOF) then result else loop lexer end in loop (Parser.makeLexer reader) end fun string_reader s = let val next = ref s in fn _ => !next before next := "" end val string_parse = fn s => parse (0, string_reader s) val file_parse = fn name => let val dev = open_in name in (parse (15,(fn i => input(dev,i)))) before close_in dev end fun prefix line len = substring(line,0,min(len,size line)) fun echo_line line = if (line = "\n") orelse (line="") then write line else if prefix line 3 = "%% " then write (substring(line,3,size(line)-3)) else if prefix line 2 = "%%" then write (substring(line,2,size(line)-2)) else write ("> " ^ line) fun convert_tabs s = implode (map (fn "\t" => " " | s => s) (explode s)); fun stream_parse dev = parse (15,(fn i => let val line = convert_tabs(input_line(dev)) val _ = echo_line line in line end)) val top_parse = fn () => parse (0, let val not_first_flag = ref(false) in fn i => (( if (!not_first_flag) then (write "> "; flush_out std_out) else not_first_flag := true ); input_line std_in) end) end (* functor Parse *) signature SYNTH = sig structure Globals: GLOBALS structure Trm: TRM structure Typ: TYP structure Leq: LEQ sharing Trm.Typ = Typ and Leq.Typ = Typ and Typ.Globals = Globals open Globals val synth: Typ.tenv -> Trm.T -> Typ.T end (* Copyright 1989 by AT&T Bell Laboratories *) (* util/strghash.sml *) (* Functorized by BCP, 1991 *) functor StrgHash() = struct val prime = 8388593 (* largest prime less than 2^23 *) val base = 128 (* the simple version -- fun hashString(str: string) : int = let fun loop (0,n) = n | loop (i,n) = let val i = i-1 val n' = (base * n + ordof(str,i)) in loop (i, (n' - prime * (n' quot prime))) end in loop (size str,0) end *) fun hashString(str: string) : int = let val l = size str in case l of 0 => 0 | 1 => ord str | 2 => ordof(str,0) + base * ordof(str,1) | 3 => ordof(str,0) + base * (ordof(str,1) + base * ordof(str,2)) | _ => let fun loop (0,n) = n | loop (i,n) = let val i = i-1 val n' = (base * n + ordof(str,i)) in loop (i, (n' - prime * (n' quot prime))) end in loop (l,0) end end end (* structure StrgHash *) functor StringUtils() : STRINGUTILS = struct end (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) (* LEXER: a signature that most lexers produced for use with SML-Yacc's outut will match. The user is responsible for declaring type token, type pos, and type svalue in the UserDeclarations section of a lexer. Note that type token is abstract in the lexer. This allows SML-Yacc to create a TOKENS signature for use with lexers produced by ML-Lex that treats the type token abstractly. Lexers that are functors parametrized by a Tokens structure matching a TOKENS signature cannot examine the structure of tokens. *) signature LEXER = sig structure UserDeclarations : sig type ('a,'b) token type pos type svalue end val makeLexer : (int -> string) -> unit -> (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token end functor FMEETLexFun(structure Tokens: FMEET_TOKENS structure Interface: INTERFACE) : LEXER= struct structure UserDeclarations = struct structure Tokens = Tokens structure Interface = Interface open Interface type pos = Interface.pos type svalue = Tokens.svalue type ('a,'b) token = ('a,'b) Tokens.token type lexresult= (svalue,pos) token val eof = fn () => Tokens.T_EOF(!line,!line) val str_begin = ref(!line); val str_const = ref([]:string list); end (* end of user routines *) exception LexError (* raised if illegal leaf action tried *) structure Internal = struct datatype yyfinstate = N of int type statedata = {fin : yyfinstate list, trans: string} (* transition & final state table *) val tab = let val s0 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000" val s1 = "\007\007\007\007\007\007\007\007\007\097\099\007\007\007\007\007\ \\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\ \\097\007\007\007\096\095\007\094\093\092\007\007\091\089\088\086\ \\084\084\084\084\084\084\084\084\084\084\083\082\080\077\076\007\ \\075\072\010\010\010\010\010\010\010\010\010\010\010\010\070\010\ \\010\010\010\066\010\010\010\010\010\010\010\065\063\062\007\007\ \\061\010\010\053\048\045\042\010\010\040\010\010\010\010\010\035\ \\031\010\026\023\019\016\010\012\010\010\010\009\007\008\007\007\ \\007" val s3 = "\100\100\100\100\100\100\100\100\100\100\101\100\100\100\100\100\ \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\ \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\ \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\ \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\ \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\ \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\ \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\ \\100" val s5 = "\102\102\102\102\102\102\102\102\102\102\104\102\102\102\102\102\ \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\ \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\ \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\ \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\ \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\ \\103\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\ \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\ \\102" val s10 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s12 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\013\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s13 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\014\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s14 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\015\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s16 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\017\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s17 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\018\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s19 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\020\011\000\000\000\000\000\ \\000" val s20 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\021\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s21 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\022\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s23 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\024\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s24 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\025\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s26 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\027\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s27 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\028\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s28 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\029\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s29 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\030\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s31 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\032\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s32 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\033\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s33 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\034\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s35 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\039\011\011\011\011\011\011\011\011\011\ \\036\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s36 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\037\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s37 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\038\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s40 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\041\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s42 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\043\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s43 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\044\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s45 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\046\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s46 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\047\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s48 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\049\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s49 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\050\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s50 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\051\011\011\011\011\011\000\000\000\000\000\ \\000" val s51 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\052\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s53 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\058\011\011\011\011\011\011\054\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s54 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\055\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s55 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\056\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s56 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\057\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s58 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\059\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s59 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\060\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s63 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\064\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000" val s66 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\067\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s67 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\068\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s68 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\069\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s70 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\071\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s72 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\073\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s73 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\ \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\ \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\ \\000\011\011\011\011\011\011\011\011\011\011\011\074\011\011\011\ \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\ \\000" val s77 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\079\078\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000" val s80 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\081\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000" val s84 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\085\085\085\085\085\085\085\085\085\085\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000" val s86 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\087\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000" val s89 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\090\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000" val s97 = "\000\000\000\000\000\000\000\000\000\098\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\098\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ \\000" in arrayoflist [{fin = [], trans = s0}, {fin = [(N 32)], trans = s1}, {fin = [(N 32)], trans = s1}, {fin = [], trans = s3}, {fin = [], trans = s3}, {fin = [], trans = s5}, {fin = [], trans = s5}, {fin = [(N 144)], trans = s0}, {fin = [(N 80),(N 144)], trans = s0}, {fin = [(N 78),(N 144)], trans = s0}, {fin = [(N 137),(N 144)], trans = s10}, {fin = [(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s12}, {fin = [(N 137)], trans = s13}, {fin = [(N 137)], trans = s14}, {fin = [(N 91),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s16}, {fin = [(N 137)], trans = s17}, {fin = [(N 3),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s19}, {fin = [(N 137)], trans = s20}, {fin = [(N 137)], trans = s21}, {fin = [(N 8),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s23}, {fin = [(N 137)], trans = s24}, {fin = [(N 12),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s26}, {fin = [(N 137)], trans = s27}, {fin = [(N 137)], trans = s28}, {fin = [(N 137)], trans = s29}, {fin = [(N 18),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s31}, {fin = [(N 137)], trans = s32}, {fin = [(N 137)], trans = s33}, {fin = [(N 122),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s35}, {fin = [(N 137)], trans = s36}, {fin = [(N 137)], trans = s37}, {fin = [(N 117),(N 137)], trans = s10}, {fin = [(N 99),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s40}, {fin = [(N 129),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s42}, {fin = [(N 137)], trans = s43}, {fin = [(N 103),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s45}, {fin = [(N 137)], trans = s46}, {fin = [(N 126),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s48}, {fin = [(N 137)], trans = s49}, {fin = [(N 137)], trans = s50}, {fin = [(N 137)], trans = s51}, {fin = [(N 24),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s53}, {fin = [(N 137)], trans = s54}, {fin = [(N 137)], trans = s55}, {fin = [(N 137)], trans = s56}, {fin = [(N 30),(N 137)], trans = s10}, {fin = [(N 137)], trans = s58}, {fin = [(N 137)], trans = s59}, {fin = [(N 96),(N 137)], trans = s10}, {fin = [(N 142),(N 144)], trans = s0}, {fin = [(N 72),(N 144)], trans = s0}, {fin = [(N 134),(N 144)], trans = s63}, {fin = [(N 132)], trans = s0}, {fin = [(N 70),(N 144)], trans = s0}, {fin = [(N 137),(N 144)], trans = s66}, {fin = [(N 137)], trans = s67}, {fin = [(N 137)], trans = s68}, {fin = [(N 112),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s70}, {fin = [(N 86),(N 137)], trans = s10}, {fin = [(N 137),(N 144)], trans = s72}, {fin = [(N 137)], trans = s73}, {fin = [(N 107),(N 137)], trans = s10}, {fin = [(N 42),(N 144)], trans = s0}, {fin = [(N 76),(N 144)], trans = s0}, {fin = [(N 52),(N 144)], trans = s77}, {fin = [(N 61)], trans = s0}, {fin = [(N 55)], trans = s0}, {fin = [(N 74),(N 144)], trans = s80}, {fin = [(N 58)], trans = s0}, {fin = [(N 44),(N 144)], trans = s0}, {fin = [(N 38),(N 144)], trans = s0}, {fin = [(N 140),(N 144)], trans = s84}, {fin = [(N 140)], trans = s84}, {fin = [(N 144)], trans = s86}, {fin = [(N 64)], trans = s0}, {fin = [(N 46),(N 144)], trans = s0}, {fin = [(N 144)], trans = s89}, {fin = [(N 83)], trans = s0}, {fin = [(N 48),(N 144)], trans = s0}, {fin = [(N 68),(N 144)], trans = s0}, {fin = [(N 66),(N 144)], trans = s0}, {fin = [(N 50),(N 144)], trans = s0}, {fin = [(N 36),(N 144)], trans = s0}, {fin = [(N 40),(N 144)], trans = s0}, {fin = [(N 32),(N 144)], trans = s97}, {fin = [(N 32)], trans = s97}, {fin = [(N 34)], trans = s0}, {fin = [(N 148)], trans = s0}, {fin = [(N 146)], trans = s0}, {fin = [(N 154)], trans = s0}, {fin = [(N 152),(N 154)], trans = s0}, {fin = [(N 150)], trans = s0}] end structure StartStates = struct datatype yystartstate = STARTSTATE of int (* start state definitions *) val COMMENT = STARTSTATE 3; val INITIAL = STARTSTATE 1; val STRING = STARTSTATE 5; end type result = UserDeclarations.lexresult exception LexerError (* raised if illegal leaf action tried *) end fun makeLexer yyinput = let val yyb = ref "\n" (* buffer *) val yybl = ref 1 (*buffer length *) val yybufpos = ref 1 (* location of next character to use *) val yygone = ref 1 (* position in file of beginning of buffer *) val yydone = ref false (* eof found yet? *) val yybegin = ref 1 (*Current 'start state' for lexer *) val YYBEGIN = fn (Internal.StartStates.STARTSTATE x) => yybegin := x fun lex () : Internal.result = let fun continue() = lex() in let fun scan (s,AcceptingLeaves : Internal.yyfinstate list list,l,i0) = let fun action (i,nil) = raise LexError | action (i,nil::l) = action (i-1,l) | action (i,(node::acts)::l) = case node of Internal.N yyk => (let val yytext = substring(!yyb,i0,i-i0) val yypos = i0+ !yygone open UserDeclarations Internal.StartStates in (yybufpos := i; case yyk of (* Application actions *) 103 => (Tokens.T_FOR(!line,!line)) | 107 => (Tokens.T_ALL(!line,!line)) | 112 => (Tokens.T_SOME(!line,!line)) | 117 => (Tokens.T_OPEN(!line,!line)) | 12 => (Tokens.T_SET(!line,!line)) | 122 => (Tokens.T_PACK(!line,!line)) | 126 => (Tokens.T_END (!line,!line)) | 129 => (Tokens.T_IN(!line,!line)) | 132 => (Tokens.T_BIGLAMBDA(!line,!line)) | 134 => (Tokens.T_LAMBDA(!line,!line)) | 137 => (Tokens.T_ID (yytext,!line,!line)) | 140 => (Tokens.T_INT_CONST (yytext,!line,!line)) | 142 => (str_begin:=(!line); str_const:=[]; YYBEGIN STRING; lex()) | 144 => (error ("ignoring illegal character" ^ yytext, !line,!line); lex()) | 146 => (next_line(); YYBEGIN INITIAL; lex()) | 148 => (lex()) | 150 => (next_line(); lex()) | 152 => (YYBEGIN INITIAL; Tokens.T_STR_CONST(implode(rev(!str_const)), !str_begin,!line)) | 154 => (str_const:=(yytext::(!str_const)); lex()) | 18 => (Tokens.T_RESET(!line,!line)) | 24 => (Tokens.T_DEBUG(!line,!line)) | 3 => (Tokens.T_USE(!line,!line)) | 30 => (Tokens.T_CHECK(!line,!line)) | 32 => (lex()) | 34 => (next_line(); lex()) | 36 => (YYBEGIN COMMENT; lex()) | 38 => (Tokens.T_COLON(!line,!line)) | 40 => (Tokens.T_DOLLAR(!line,!line)) | 42 => (Tokens.T_AT(!line,!line)) | 44 => (Tokens.T_EOF(!line,!line)) | 46 => (Tokens.T_DOT(!line,!line)) | 48 => (Tokens.T_COMMA(!line,!line)) | 50 => (Tokens.T_APOST(!line,!line)) | 52 => (Tokens.T_EQ(!line,!line)) | 55 => (Tokens.T_DOUBLEEQ(!line,!line)) | 58 => (Tokens.T_LEQ(!line,!line)) | 61 => (Tokens.T_DARROW(!line,!line)) | 64 => (Tokens.T_INTER(!line,!line)) | 66 => (Tokens.T_LPAREN(!line,!line)) | 68 => (Tokens.T_RPAREN(!line,!line)) | 70 => (Tokens.T_LBRACK(!line,!line)) | 72 => (Tokens.T_RBRACK(!line,!line)) | 74 => (Tokens.T_LANGLE(!line,!line)) | 76 => (Tokens.T_RANGLE(!line,!line)) | 78 => (Tokens.T_LCURLY(!line,!line)) | 8 => (Tokens.T_TYPE(!line,!line)) | 80 => (Tokens.T_RCURLY(!line,!line)) | 83 => (Tokens.T_ARROW(!line,!line)) | 86 => (Tokens.T_NS(!line,!line)) | 91 => (Tokens.T_WITH(!line,!line)) | 96 => (Tokens.T_CASE(!line,!line)) | 99 => (Tokens.T_OF(!line,!line)) | _ => raise Internal.LexerError ) end ) val {fin,trans} = Internal.tab sub s val NewAcceptingLeaves = fin::AcceptingLeaves in if l = !yybl then if trans = #trans(Internal.tab sub 0) then action(l,NewAcceptingLeaves) else let val newchars= if !yydone then "" else yyinput 1024 in if (size newchars)=0 then (yydone := true; if (l=i0) then UserDeclarations.eof () else action(l,NewAcceptingLeaves)) else (if i0=l then yyb := newchars else yyb := substring(!yyb,i0,l-i0)^newchars; yygone := !yygone+i0; yybl := size (!yyb); scan (s,AcceptingLeaves,l-i0,0)) end else let val NewChar = ordof(!yyb,l) val NewState = if NewChar<128 then ordof(trans,NewChar) else ordof(trans,128) in if NewState=0 then action(l,NewAcceptingLeaves) else scan(NewState,NewAcceptingLeaves,l+1,i0) end end (* val start= if substring(!yyb,!yybufpos-1,1)="\n" then !yybegin+1 else !yybegin *) in scan(!yybegin (* start *),nil,!yybufpos,!yybufpos) end end in lex end end functor Registry( type registeredtype ): REGISTRY = struct type registeredtype = registeredtype val registry = ref(nil: (string * (registeredtype->unit)) list) fun register name callback = registry := (name,callback)::(!registry) fun registerflag name flagref = registry := (name,(fn b => flagref := b))::(!registry) exception NotRegistered of string fun set_flag name v = let fun f [] = raise NotRegistered(name) | f ((n,callback)::tl) = if name=n then (callback v) else f tl in f (!registry) end fun set_all v = let fun f [] = () | f ((n,callback)::tl) = (callback v; f tl) in f (!registry) end end functor Typ( structure Globals: GLOBALS ) : TYPPVT = struct structure Globals = Globals open Globals open Pp datatype pretyp = PRETVAR of Id.T | PREARROW of pretyp * pretyp | PREALL of Id.T * pretyp * pretyp | PREMEET of pretyp list datatype T = TVAR of unit * int | ARROW of unit * T * T | ALL of {name:Id.T} * T * T | MEET of unit * (T list) type idindex = int val NS = MEET ((),[]) exception UnknownId of string datatype tenvelt = BND of Id.T * T | ABB of Id.T * T | VBND of Id.T * T datatype tenv = TENV of tenvelt list fun push_bound (TENV(te)) i t = TENV(BND(i,t)::te) fun push_abbrev (TENV(te)) i t = TENV(ABB(i,t)::te) fun push_binding (TENV(te)) i t = TENV(VBND(i,t)::te) val empty_tenv = TENV(nil) fun index (TENV(bvs)) i = let fun ind [] n = raise UnknownId(Id.tostr i) | ind (BND(i',_)::rest) n = if Id.== i i' then n else ind rest (n+1) | ind (VBND(i',_)::rest) n = if Id.== i i' then n else ind rest (n+1) | ind (ABB(i',_)::rest) n = if Id.== i i' then n else ind rest (n+1) in ind bvs 0 end exception TypeVariableOutOfRange of int fun old_lookup_name (TENV(te)) i = (case (nth (te,i)) of BND(name,_) => name | VBND(name,_) => name | ABB(name,_) => name) handle Nth => Id.intern(("<BAD INDEX: " ^ (makestring i) ^ ">")) fun lookup_name (TENV(te)) i = let fun l [] _ _ = Id.intern(("<BAD INDEX: " ^ (makestring i) ^ ">")) | l (hd::tl) rest 0 = let val name = case hd of BND(n,_) => n | VBND(n,_) => n | ABB(n,_) => n in if memq Id.== rest name then Id.intern ((Id.tostr name) ^ "^" ^ (makestring i)) else name end | l (hd::tl) rest j = let val name = case hd of BND(n,_) => n | VBND(n,_) => n | ABB(n,_) => n in l tl (name::rest) (j-1) end in l te [] i end exception WrongKindOfId of tenv * int * string fun lookup (TENV(te)) i = nth (te,i) handle Nth => raise TypeVariableOutOfRange(i) exception TriedToPopEmptyTEnv fun pop (TENV(hd::tl)) = TENV(tl) | pop _ = raise TriedToPopEmptyTEnv fun inner_relocate offset cutoff t = let fun r c (TVAR((),i)) = if i>=c then TVAR((),i + offset) else TVAR((),i) | r c (ARROW((),t1,t2)) = ARROW((), r c t1, r c t2) | r c (ALL({name=i},t1,t2)) = ALL({name=i}, r c t1, r (c+1) t2) | r c (MEET((),ts)) = MEET((), map (fn t => r c t) ts) in r cutoff t end fun relocate offset t = inner_relocate offset 0 t fun lookup_and_relocate (te) i = case lookup te i of BND(n,b) => BND(n, relocate (i+1) b) | VBND(n,b) => VBND(n, relocate (i+1) b) | ABB(n,b) => ABB(n, relocate (i+1) b) fun lookup_and_relocate_bound te i = case lookup_and_relocate te i of BND(_,b) => b | VBND(n,_) => raise WrongKindOfId(te,i,"tvar") | ABB(n,_) => raise WrongKindOfId(te,i,"tvar") fun lookup_and_relocate_binding te i = case lookup_and_relocate te i of BND(n,b) => raise WrongKindOfId(te,i,"var") | VBND(n,b) => b | ABB(n,b) => raise WrongKindOfId(te,i,"var") fun lookup_abbrev te i = case lookup_and_relocate te i of BND(n,_) => raise WrongKindOfId(te,i,"tabbrev") | VBND(n,b) => raise WrongKindOfId(te,i,"tabbrev") | ABB(n,b) => b fun debruijnify te (PRETVAR i) = TVAR((), index te i) | debruijnify te (PREARROW (pt1,pt2)) = ARROW((), debruijnify te pt1, debruijnify te pt2) | debruijnify te (PREALL (i,pt1,pt2)) = ALL({name=i}, debruijnify te pt1, debruijnify (push_bound te i NS) pt2) | debruijnify te (PREMEET pts) = MEET((), map (fn pt => debruijnify te pt) pts) fun tsubst_top targ tbody = let fun s i (t as TVAR(x,i')) = if i = i' then relocate i targ else if i < i' then TVAR(x,i'-1) else t | s i (ARROW(x,t1,t2)) = ARROW(x, s i t1, s i t2) | s i (ALL(x,t1,t2)) = ALL(x, s i t1, s (i+1) t2) | s i (MEET(x,ts)) = MEET(x, map (fn t => s i t) ts) in s 0 tbody end fun prt pp te t = let fun p te (TVAR(_,i)) = Pp.pwrite pp (Id.tostr (lookup_name te i)) | p te (ARROW(_,t1,t2)) = (Pp.pwrite pp "("; p te t1; Pp.pwrite pp "->"; p te t2; Pp.pwrite pp ")") | p te (ALL({name=i},t1,t2)) = (Pp.pwrite pp "(All "; Pp.pwrite pp (Id.tostr i); Pp.pwrite pp "<="; p te t1; Pp.pwrite pp ". "; p (push_bound te i t1) t2; Pp.pwrite pp ")") | p te (MEET(_,[])) = Pp.pwrite pp "NS" | p te (MEET(_,ts)) = (Pp.pwrite pp "/\\["; plist te ts; Pp.pwrite pp "]") and plist te [] = () | plist te [t] = p te t | plist te (hd::tl) = (p te hd; pwrite pp ","; plist te tl) in p te t end val short_tenvs = ref(true); val _ = registerflag "shorttenvs" short_tenvs; fun prt_tenv pp (TENV(te')) = let fun p [] = () | p [(BND(i,t))] = (Pp.pwrite pp (Id.tostr i); Pp.pwrite pp "<="; prt pp (TENV([])) t) | p ((BND(i,t))::tl) = (if (!short_tenvs) then pwrite pp "... " else p tl; Pp.pwrite pp ", "; Pp.break pp false 0; Pp.pwrite pp (Id.tostr i); Pp.pwrite pp "<="; prt pp (TENV(tl)) t) | p [(VBND(i,t))] = (Pp.pwrite pp (Id.tostr i); Pp.pwrite pp ":"; prt pp (TENV([])) t) | p ((VBND(i,t))::tl) = (if (!short_tenvs) then pwrite pp "... " else p tl; Pp.pwrite pp ", "; Pp.break pp false 0; Pp.pwrite pp (Id.tostr i); Pp.pwrite pp ":"; prt pp (TENV(tl)) t) | p [(ABB(i,t))] = (Pp.pwrite pp (Id.tostr i); Pp.pwrite pp "="; prt pp (TENV([])) t) | p ((ABB(i,t))::tl) = (if (!short_tenvs) then pwrite pp "... " else p tl; Pp.pwrite pp ", "; Pp.break pp false 0; Pp.pwrite pp (Id.tostr i); Pp.pwrite pp "="; prt pp (TENV(tl)) t) in Pp.pwrite pp "{"; Pp.setb pp; p te'; Pp.endb pp; Pp.pwrite pp "}" end end functor Leq( structure Typ: TYPPVT structure Globals: GLOBALS sharing Typ.Globals = Globals ) : LEQ = struct structure Typ = Typ structure Globals = Globals open Globals open Typ datatype lhsqueue = ARROW_LHS of Typ.T | ALL_LHS of Id.T * Typ.T datatype rhs_flag = EXPAND | FIX val DEBUG = ref(false) val _ = (registerflag "leq" DEBUG; registerflag "Leq" DEBUG) fun describe_rest pp te [] t flag = (Pp.pwrite pp "] -> "; Typ.prt pp te t; case flag of EXPAND => Pp.pwrite pp " (EXPAND)? " | FIX => Pp.pwrite pp " (FIX)? ") | describe_rest pp te [ARROW_LHS(t1)] t2 flag = (Typ.prt pp te t1; describe_rest pp te [] t2 flag) | describe_rest pp te ((ARROW_LHS(t1))::X2) t2 flag = (Typ.prt pp te t1; Pp.pwrite pp ","; describe_rest pp te X2 t2 flag) | describe_rest pp te [ALL_LHS(v,t1)] t2 flag = (Pp.pwrite pp (Id.tostr v); Pp.pwrite pp "<="; Typ.prt pp te t1; describe_rest pp (push_bound te v t1) [] t2 flag) | describe_rest pp te ((ALL_LHS(v,t1))::X2) t2 flag = (Pp.pwrite pp (Id.tostr v); Pp.pwrite pp "<="; Typ.prt pp te t1; Pp.pwrite pp ","; describe_rest pp (push_bound te v t1) X2 t2 flag) fun describe_problem pp te s X t flag = (Pp.setb pp; Typ.prt pp te s; Pp.break pp true ~3; Pp.pwrite pp " <= "; Pp.pwrite pp "["; describe_rest pp te X t flag; Pp.endb pp) fun bindings_in [] = 0 | bindings_in (ARROW_LHS(_)::tl) = bindings_in tl | bindings_in (ALL_LHS(_)::tl) = 1 + (bindings_in tl) fun leqq' te s X (MEET(_,ts)) EXPAND = forall (fn t => leqq te s X t EXPAND) ts | leqq' te s X (ARROW(_,t1,t2)) EXPAND = leqq te s (X@[ARROW_LHS(t1)]) t2 EXPAND | leqq' te s X (ALL({name=i},t1,t2)) EXPAND = leqq te s (X@[ALL_LHS(i,t1)]) t2 EXPAND | leqq' te s X (t as TVAR(_,vt)) EXPAND = let val bx = bindings_in X in if vt < bx then leqq te s X t FIX else case Typ.lookup te (vt - bx) of BND(_,_) => leqq te s X t FIX | VBND(n,_) => raise Typ.WrongKindOfId(te, vt - bx,"tvar or tabbrev") | ABB(_,ab) => leqq te s X (Typ.relocate (vt + bx) ab) EXPAND end | leqq' te (MEET(_,ss)) X (t as (TVAR(_,vt))) FIX = forsome (fn s => leqq te s X t FIX) ss | leqq' te (ARROW(_,s1,s2)) (ARROW_LHS(t1)::X) (t as (TVAR(_,vt))) FIX = (leqq te t1 [] s1 EXPAND) andalso (leqq te s2 X t FIX) | leqq' te (ALL(_,s1,s2)) (ALL_LHS(i,t1)::X) (t as (TVAR(_,vt))) FIX = (leqq (push_bound te i t1) s2 X t FIX) andalso (leqq te t1 [] s1 EXPAND) | leqq' te (TVAR(_,vs)) X (t as (TVAR(_,vt))) FIX = (vs = vt andalso (null X)) orelse (case lookup_and_relocate te vs of BND(_,bnd) => (leqq te bnd X t FIX) | VBND(n,ab) => raise Typ.WrongKindOfId(te,vs,"tvar or tabbrev") | ABB(_,ab) => (leqq te ab X t FIX)) | leqq' te s X t flag = false and leqq te s X t flag = wrap DEBUG "leqq" (fn () => leqq' te s X t flag) (fn () => describe_problem (stdpp()) te s X t flag) (fn b => write (if b then "Yes" else "No")) (* and leqq te s X t = leqq' te s X t *) fun leq te s t = leqq te s [] t EXPAND end (* Gene Rollins School of Computer Science Carnegie-Mellon University Pittsburgh, PA 15213 rollins@cs.cmu.edu *) functor HashFun () = struct val version = 1.0 type ('a,'b) table = ('a*'a->bool) * (('a*int*'b) list array) * int fun create (sample'key :'1a) (equality :'1a * '1a -> bool) table'size (sample'value :'1b) :('1a,'1b) table = let val mt = tl [(sample'key, 0, sample'value)] in (equality, array (table'size, mt), table'size) end val defaultSize = 97 (* a prime; or try primes 37, 997 *) fun defaultEqual ((x :string), (y :string)) :bool = (x = y) fun createDefault (sample'value :'1b) :(string,'1b) table = let val mt = tl [("", 0, sample'value)] in (defaultEqual, array (defaultSize, mt), defaultSize) end fun enter ((equal, table, table'size) :('a,'b) table) key hash value = let val place = hash mod table'size val bucket = table sub place fun put'in [] = [(key,hash,value)] | put'in ((k,h,v)::tail) = if (h = hash) andalso equal (k, key) then (key,hash,value)::tail else (k,h,v)::(put'in tail) in update (table, place, put'in bucket) end fun remove ((equal, table, table'size) :('a,'b) table) key hash = let val place = hash mod table'size val bucket = table sub place fun take'out [] = [] | take'out ((k,h,v)::tail) = if (h = hash) andalso equal (k, key) then tail else (k,h,v)::(take'out tail) in update (table, place, take'out bucket) end fun lookup ((equal, table, table'size) :('a,'b) table) key hash = let val place = hash mod table'size val bucket = table sub place fun get'out [] = NONE | get'out ((k,h,v)::tail) = if (h = hash) andalso equal (k, key) then SOME v else get'out tail in get'out bucket end fun print ((_, table, table'size) :('a,'b) table) (print'key :'a -> unit) (print'value :'b -> unit) = let fun pr'bucket [] = () | pr'bucket ((key,hash,value)::rest) = (print'key key; String.print ": "; Integer.print hash; String.print ": "; print'value value; String.print "\n"; pr'bucket rest) fun pr i = if i >= table'size then () else case (table sub i) of [] => (pr (i+1)) | (b as (h::t)) => (String.print "["; Integer.print i; String.print "]\n"; pr'bucket b; pr (i+1)) in pr 0 end fun scan ((_, table, table'size) :('a,'b) table) operation = let fun map'bucket [] = () | map'bucket ((key,hash,value)::rest) = (operation key hash value; map'bucket rest) fun iter i = if i >= table'size then () else (map'bucket (table sub i); iter (i+1)) in iter 0 end fun fold ((_, table, table'size) :('a, 'b) table) (operation :'a -> int -> 'b -> 'g -> 'g) (init :'g) :'g = let fun fold'bucket [] acc = acc | fold'bucket ((key,hash,value)::rest) acc = fold'bucket rest (operation key hash value acc) fun iter i acc = if i >= table'size then acc else iter (i+1) (fold'bucket (table sub i) acc) in iter 0 init end fun scanUpdate ((_, table, table'size) :('a,'b) table) operation = let fun map'bucket [] = [] | map'bucket ((key,hash,value)::rest) = ((key,hash,operation key hash value)::(map'bucket rest)) fun iter i = if i >= table'size then () else (update (table, i, map'bucket (table sub i)); iter (i+1)) in iter 0 end fun eliminate ((_, table, table'size) :('a,'b) table) predicate = let fun map'bucket [] = [] | map'bucket ((key,hash,value)::rest) = if predicate key hash value then map'bucket rest else (key,hash,value)::(map'bucket rest) fun iter i = if i >= table'size then () else (update (table, i, map'bucket (table sub i)); iter (i+1)) in iter 0 end fun bucketLengths ((_, table, table'size) :('a,'b) table) (maxlen :int) :int array = let val count :int array = array (maxlen+1, 0) fun inc'sub x = let val y = min (x, maxlen) in update (count, y, (count sub y) + 1) end fun iter i = if i >= table'size then () else (inc'sub (length (table sub i)); iter (i+1)) in iter 0; count end end (* Cribbed from... ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) signature ORDSET = sig type set type elem exception Select_arb val app : (elem -> 'b) -> set -> unit and card: set -> int and closure: set * (elem -> set) -> set and difference: set * set -> set and elem_eq: (elem * elem -> bool) and elem_gt : (elem * elem -> bool) and empty: set and exists: (elem * set) -> bool and find : (elem * set) -> elem option and fold: ((elem * 'b) -> 'b) -> set -> 'b -> 'b and insert: (elem * set) -> set and is_empty: set -> bool and make_list: set -> elem list and make_set: (elem list -> set) and partition: (elem -> bool) -> (set -> set * set) and remove: (elem * set) -> set and revfold: ((elem * 'b) -> 'b) -> set -> 'b -> 'b and select_arb: set -> elem and set_eq: (set * set) -> bool and set_gt: (set * set) -> bool and singleton: (elem -> set) and union: set * set -> set end signature TABLE = sig type 'a table type key val size : 'a table -> int val empty: 'a table val exists: (key * 'a table) -> bool val find : (key * 'a table) -> 'a option val insert: ((key * 'a) * 'a table) -> 'a table val make_table : (key * 'a ) list -> 'a table val make_list : 'a table -> (key * 'a) list val fold : ((key * 'a) * 'b -> 'b) -> 'a table -> 'b -> 'b end signature HASH = sig type table type elem val size : table -> int val add : elem * table -> table val find : elem * table -> int option val exists : elem * table -> bool val empty : table end; (* Cribbed from... ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) (*III import "tarditi.sig"; III*) (* Implementation of ordered sets using ordered lists and red-black trees. The code for red-black trees was originally written by Norris Boyd, which was modified for use here. *) (* ordered sets implemented using ordered lists. Upper bound running times for functions implemented here: app = O(n) card = O(n) closure = O(n^2) difference = O(n+m), where n,m = the size of the two sets used here. empty = O(1) exists = O(n) find = O(n) fold = O(n) insert = O(n) is_empty = O(1) make_list = O(1) make_set = O(n^2) partition = O(n) remove = O(n) revfold = O(n) select_arb = O(1) set_eq = O(n), where n = the cardinality of the smaller set set_gt = O(n), ditto singleton = O(1) union = O(n+m) *) functor ListOrdSet(B : sig type elem val gt : elem * elem -> bool val eq : elem * elem -> bool end ) : ORDSET = struct type elem = B.elem val elem_gt = B.gt val elem_eq = B.eq type set = elem list exception Select_arb val empty = nil val insert = fn (key,s) => let fun f (l as (h::t)) = if elem_gt(key,h) then h::(f t) else if elem_eq(key,h) then key::t else key::l | f nil = [key] in f s end val select_arb = fn nil => raise Select_arb | a::b => a val exists = fn (key,s) => let fun f (h::t) = if elem_gt(key,h) then f t else elem_eq(h,key) | f nil = false in f s end val find = fn (key,s) => let fun f (h::t) = if elem_gt(key,h) then f t else if elem_eq(h,key) then SOME h else NONE | f nil = NONE in f s end val revfold = List.revfold val fold = List.fold val app = List.app fun set_eq(h::t,h'::t') = (case elem_eq(h,h') of true => set_eq(t,t') | a => a) | set_eq(nil,nil) = true | set_eq _ = false fun set_gt(h::t,h'::t') = (case elem_gt(h,h') of false => (case (elem_eq(h,h')) of true => set_gt(t,t') | a => a) | a => a) | set_gt(_::_,nil) = true | set_gt _ = false fun union(a as (h::t),b as (h'::t')) = if elem_gt(h',h) then h::union(t,b) else if elem_eq(h,h') then h::union(t,t') else h'::union(a,t') | union(nil,s) = s | union(s,nil) = s val make_list = fn s => s val is_empty = fn nil => true | _ => false val make_set = fn l => List.fold insert l nil val partition = fn f => fn s => fold (fn (e,(yes,no)) => if (f e) then (e::yes,no) else (e::no,yes)) s (nil,nil) val remove = fn (e,s) => let fun f (l as (h::t)) = if elem_gt(h,e) then l else if elem_eq(h,e) then t else h::(f t) | f nil = nil in f s end (* difference: X-Y *) fun difference (nil,_) = nil | difference (r,nil) = r | difference (a as (h::t),b as (h'::t')) = if elem_gt (h',h) then h::difference(t,b) else if elem_eq(h',h) then difference(t,t') else difference(a,t') fun singleton X = [X] fun card(S) = fold (fn (a,count) => count+1) S 0 local fun closure'(from, f, result) = if is_empty from then result else let val (more,result) = fold (fn (a,(more',result')) => let val more = f a val new = difference(more,result) in (union(more',new),union(result',new)) end) from (empty,result) in closure'(more,f,result) end in fun closure(start, f) = closure'(start, f, start) end end (* ordered set implemented using red-black trees: Upper bound running time of the functions below: app: O(n) card: O(n) closure: O(n^2 ln n) difference: O(n ln n) empty: O(1) exists: O(ln n) find: O(ln n) fold: O(n) insert: O(ln n) is_empty: O(1) make_list: O(n) make_set: O(n ln n) partition: O(n ln n) remove: O(n ln n) revfold: O(n) select_arb: O(1) set_eq: O(n) set_gt: O(n) singleton: O(1) union: O(n ln n) *) functor RbOrdSet (B : sig type elem val eq : (elem*elem) -> bool val gt : (elem*elem) -> bool end ) : ORDSET = struct type elem = B.elem val elem_gt = B.gt val elem_eq = B.eq datatype Color = RED | BLACK abstype set = EMPTY | TREE of (B.elem * Color * set * set) with exception Select_arb val empty = EMPTY fun insert(key,t) = let fun f EMPTY = TREE(key,RED,EMPTY,EMPTY) | f (TREE(k,BLACK,l,r)) = if elem_gt (key,k) then case f r of r as TREE(rk,RED, rl as TREE(rlk,RED,rll,rlr),rr) => (case l of TREE(lk,RED,ll,lr) => TREE(k,RED,TREE(lk,BLACK,ll,lr), TREE(rk,BLACK,rl,rr)) | _ => TREE(rlk,BLACK,TREE(k,RED,l,rll), TREE(rk,RED,rlr,rr))) | r as TREE(rk,RED,rl, rr as TREE(rrk,RED,rrl,rrr)) => (case l of TREE(lk,RED,ll,lr) => TREE(k,RED,TREE(lk,BLACK,ll,lr), TREE(rk,BLACK,rl,rr)) | _ => TREE(rk,BLACK,TREE(k,RED,l,rl),rr)) | r => TREE(k,BLACK,l,r) else if elem_gt(k,key) then case f l of l as TREE(lk,RED,ll, lr as TREE(lrk,RED,lrl,lrr)) => (case r of TREE(rk,RED,rl,rr) => TREE(k,RED,TREE(lk,BLACK,ll,lr), TREE(rk,BLACK,rl,rr)) | _ => TREE(lrk,BLACK,TREE(lk,RED,ll,lrl), TREE(k,RED,lrr,r))) | l as TREE(lk,RED, ll as TREE(llk,RED,lll,llr), lr) => (case r of TREE(rk,RED,rl,rr) => TREE(k,RED,TREE(lk,BLACK,ll,lr), TREE(rk,BLACK,rl,rr)) | _ => TREE(lk,BLACK,ll,TREE(k,RED,lr,r))) | l => TREE(k,BLACK,l,r) else TREE(key,BLACK,l,r) | f (TREE(k,RED,l,r)) = if elem_gt(key,k) then TREE(k,RED,l, f r) else if elem_gt(k,key) then TREE(k,RED, f l, r) else TREE(key,RED,l,r) in case f t of TREE(k,RED, l as TREE(_,RED,_,_), r) => TREE(k,BLACK,l,r) | TREE(k,RED, l, r as TREE(_,RED,_,_)) => TREE(k,BLACK,l,r) | t => t end fun select_arb (TREE(k,_,l,r)) = k | select_arb EMPTY = raise Select_arb fun exists(key,t) = let fun look EMPTY = false | look (TREE(k,_,l,r)) = if elem_gt(k,key) then look l else if elem_gt(key,k) then look r else true in look t end fun find(key,t) = let fun look EMPTY = NONE | look (TREE(k,_,l,r)) = if elem_gt(k,key) then look l else if elem_gt(key,k) then look r else SOME k in look t end fun revfold f t start = let fun scan (EMPTY,value) = value | scan (TREE(k,_,l,r),value) = scan(r,f(k,scan(l,value))) in scan(t,start) end fun fold f t start = let fun scan(EMPTY,value) = value | scan(TREE(k,_,l,r),value) = scan(l,f(k,scan(r,value))) in scan(t,start) end fun app f t = let fun scan EMPTY = () | scan(TREE(k,_,l,r)) = (scan l; f k; scan r) in scan t end (* equal_tree : test if two trees are equal. Two trees are equal if the set of leaves are equal *) fun set_eq (tree1 as (TREE _),tree2 as (TREE _)) = let datatype pos = L | R | M exception Done fun getvalue(stack as ((a,position)::b)) = (case a of (TREE(k,_,l,r)) => (case position of L => getvalue ((l,L)::(a,M)::b) | M => (k,case r of EMPTY => b | _ => (a,R)::b) | R => getvalue ((r,L)::b) ) | EMPTY => getvalue b ) | getvalue(nil) = raise Done fun f (nil,nil) = true | f (s1 as (_ :: _),s2 as (_ :: _ )) = let val (v1,news1) = getvalue s1 and (v2,news2) = getvalue s2 in (elem_eq(v1,v2)) andalso f(news1,news2) end | f _ = false in f ((tree1,L)::nil,(tree2,L)::nil) handle Done => false end | set_eq (EMPTY,EMPTY) = true | set_eq _ = false (* gt_tree : Test if tree1 is greater than tree 2 *) fun set_gt (tree1,tree2) = let datatype pos = L | R | M exception Done fun getvalue(stack as ((a,position)::b)) = (case a of (TREE(k,_,l,r)) => (case position of L => getvalue ((l,L)::(a,M)::b) | M => (k,case r of EMPTY => b | _ => (a,R)::b) | R => getvalue ((r,L)::b) ) | EMPTY => getvalue b ) | getvalue(nil) = raise Done fun f (nil,nil) = false | f (s1 as (_ :: _),s2 as (_ :: _ )) = let val (v1,news1) = getvalue s1 and (v2,news2) = getvalue s2 in (elem_gt(v1,v2)) orelse (elem_eq(v1,v2) andalso f(news1,news2)) end | f (_,nil) = true | f (nil,_) = false in f ((tree1,L)::nil,(tree2,L)::nil) handle Done => false end fun is_empty S = (let val _ = select_arb S in false end handle Select_arb => true) fun make_list S = fold (op ::) S nil fun make_set l = List.fold insert l empty fun partition F S = fold (fn (a,(Yes,No)) => if F(a) then (insert(a,Yes),No) else (Yes,insert(a,No))) S (empty,empty) fun remove(X, XSet) = let val (YSet, _) = partition (fn a => not (elem_eq (X, a))) XSet in YSet end fun difference(Xs, Ys) = fold (fn (p as (a,Xs')) => if exists(a,Ys) then Xs' else insert p) Xs empty fun singleton X = insert(X,empty) fun card(S) = fold (fn (_,count) => count+1) S 0 fun union(Xs,Ys)= fold insert Ys Xs local fun closure'(from, f, result) = if is_empty from then result else let val (more,result) = fold (fn (a,(more',result')) => let val more = f a val new = difference(more,result) in (union(more',new),union(result',new)) end) from (empty,result) in closure'(more,f,result) end in fun closure(start, f) = closure'(start, f, start) end end end (* signature TABLE = sig type 'a table type key val size : 'a table -> int val empty: 'a table val exists: (key * 'a table) -> bool val find : (key * 'a table) -> 'a option val insert: ((key * 'a) * 'a table) -> 'a table val make_table : (key * 'a ) list -> 'a table val make_list : 'a table -> (key * 'a) list val fold : ((key * 'a) * 'b -> 'b) -> 'a table -> 'b -> 'b end *) functor Table (B : sig type key val gt : (key * key) -> bool end ) : TABLE = struct datatype Color = RED | BLACK type key = B.key abstype 'a table = EMPTY | TREE of ((B.key * 'a ) * Color * 'a table * 'a table) with val empty = EMPTY fun insert(elem as (key,data),t) = let val key_gt = fn (a,_) => B.gt(key,a) val key_lt = fn (a,_) => B.gt(a,key) fun f EMPTY = TREE(elem,RED,EMPTY,EMPTY) | f (TREE(k,BLACK,l,r)) = if key_gt k then case f r of r as TREE(rk,RED, rl as TREE(rlk,RED,rll,rlr),rr) => (case l of TREE(lk,RED,ll,lr) => TREE(k,RED,TREE(lk,BLACK,ll,lr), TREE(rk,BLACK,rl,rr)) | _ => TREE(rlk,BLACK,TREE(k,RED,l,rll), TREE(rk,RED,rlr,rr))) | r as TREE(rk,RED,rl, rr as TREE(rrk,RED,rrl,rrr)) => (case l of TREE(lk,RED,ll,lr) => TREE(k,RED,TREE(lk,BLACK,ll,lr), TREE(rk,BLACK,rl,rr)) | _ => TREE(rk,BLACK,TREE(k,RED,l,rl),rr)) | r => TREE(k,BLACK,l,r) else if key_lt k then case f l of l as TREE(lk,RED,ll, lr as TREE(lrk,RED,lrl,lrr)) => (case r of TREE(rk,RED,rl,rr) => TREE(k,RED,TREE(lk,BLACK,ll,lr), TREE(rk,BLACK,rl,rr)) | _ => TREE(lrk,BLACK,TREE(lk,RED,ll,lrl), TREE(k,RED,lrr,r))) | l as TREE(lk,RED, ll as TREE(llk,RED,lll,llr), lr) => (case r of TREE(rk,RED,rl,rr) => TREE(k,RED,TREE(lk,BLACK,ll,lr), TREE(rk,BLACK,rl,rr)) | _ => TREE(lk,BLACK,ll,TREE(k,RED,lr,r))) | l => TREE(k,BLACK,l,r) else TREE(elem,BLACK,l,r) | f (TREE(k,RED,l,r)) = if key_gt k then TREE(k,RED,l, f r) else if key_lt k then TREE(k,RED, f l, r) else TREE(elem,RED,l,r) in case f t of TREE(k,RED, l as TREE(_,RED,_,_), r) => TREE(k,BLACK,l,r) | TREE(k,RED, l, r as TREE(_,RED,_,_)) => TREE(k,BLACK,l,r) | t => t end fun exists(key,t) = let fun look EMPTY = false | look (TREE((k,_),_,l,r)) = if B.gt(k,key) then look l else if B.gt(key,k) then look r else true in look t end fun find(key,t) = let fun look EMPTY = NONE | look (TREE((k,data),_,l,r)) = if B.gt(k,key) then look l else if B.gt(key,k) then look r else SOME data in look t end fun fold f t start = let fun scan(EMPTY,value) = value | scan(TREE(k,_,l,r),value) = scan(l,f(k,scan(r,value))) in scan(t,start) end fun make_table l = List.fold insert l empty fun size S = fold (fn (_,count) => count+1) S 0 fun make_list table = fold (op ::) table nil end end; (* assumes that a functor Table with signature TABLE from table.sml is in the environment *) (* signature HASH = sig type table type elem val size : table -> int val add : elem * table -> table val find : elem * table -> int option val exists : elem * table -> bool val empty : table end *) (* hash: creates a hash table of size n which assigns each distinct member a unique integer between 0 and n-1 *) functor Hash(B : sig type elem val gt : elem * elem -> bool end) : HASH = struct type elem=B.elem structure HashTable = Table(type key=B.elem val gt = B.gt) type table = {count : int, table : int HashTable.table} val empty = {count=0,table=HashTable.empty} val size = fn {count,table} => count val add = fn (e,{count,table}) => {count=count+1,table=HashTable.insert((e,count),table)} val find = fn (e,{table,count}) => HashTable.find(e,table) val exists = fn (e,{table,count}) => HashTable.exists(e,table) end; (*III import "interface.sig"; III*) functor Interface () : INTERFACE = struct type pos = int val line = ref 0 fun init_line () = (line := 0) fun next_line () = (line := !line + 1) fun error (errmsg,line:pos,_) = output (std_out, ("Line " ^ (makestring line) ^ ": " ^ errmsg ^ "\n")) end (* functor INTERFACE *) functor Globals( structure Wr: WR structure Pp: PP structure WrMgt: WRMGT structure ListUtils: LISTUTILS structure StringUtils: STRINGUTILS structure DebugUtils: DEBUGUTILS structure Id: ID structure Registry: REGISTRY sharing Pp.Wr = Wr and WrMgt.Pp = Pp and type Registry.registeredtype = bool ) : GLOBALS = struct structure Wr = Wr; open Wr; structure Pp = Pp; open Pp; structure WrMgt = WrMgt; open WrMgt; structure Id = Id; structure Registry = Registry open ListUtils open StringUtils open DebugUtils open Registry exception CantHappen end signature TRMPVT = sig structure Globals: GLOBALS structure Typ: TYPPVT sharing Typ.Globals = Globals open Globals datatype pretrm = PREVAR of Id.T | PREABS of Id.T * Typ.pretyp * pretrm | PREAPP of pretrm * pretrm | PRETABS of Id.T * Typ.pretyp * pretrm | PRETAPP of pretrm * Typ.pretyp | PREFOR of Id.T * (Typ.pretyp list) * pretrm datatype T = VAR of unit * int | ABS of {name:Id.T} * Typ.T * T | APP of unit * T * T | TABS of {name:Id.T} * Typ.T * T | TAPP of unit * T * Typ.T | FOR of {name:Id.T} * (Typ.T list) * T exception UnknownId of string val debruijnify: Typ.tenv -> pretrm -> T val prt: Pp.Pp -> Typ.tenv -> T -> unit end functor DebugUtils( structure WrMgt: WRMGT ) : DEBUGUTILS = struct open WrMgt open Pp; val level = ref(0); (* $$$ belongs in globals: *) fun unwind_protect f cleanup = (f()) handle e => (cleanup(); raise e) fun do_wrap pp name f pbefore pafter = (pwrite pp "["; setb pp; pwrite pp (makestring (!level)); pwrite pp "] "; pwrite pp name; pwrite pp "? "; pbefore(); pwrite pp "\n"; level := (!level) + 1; let val result = unwind_protect f (fn () => level := (!level) - 1) in level := (!level) - 1; break pp true ~3; pwrite pp " ["; pwrite pp (makestring (!level)); pwrite pp "] "; pwrite pp name; pwrite pp ": "; pafter(result); pwrite pp "\n"; endb pp; result end ) fun wrap DEBUG name f pbefore pafter = if (not (!DEBUG)) then f() else do_wrap (stdpp()) name f pbefore pafter; end functor Trm( structure Globals: GLOBALS structure Typ: TYPPVT sharing Typ.Globals = Globals ) : TRMPVT = struct structure Globals = Globals structure Typ = Typ open Globals open Typ open Pp datatype pretrm = PREVAR of Id.T | PREABS of Id.T * pretyp * pretrm | PREAPP of pretrm * pretrm | PRETABS of Id.T * pretyp * pretrm | PRETAPP of pretrm * pretyp | PREFOR of Id.T * (pretyp list) * pretrm datatype T = VAR of unit * int | ABS of {name:Id.T} * Typ.T * T | APP of unit * T * T | TABS of {name:Id.T} * Typ.T * T | TAPP of unit * T * Typ.T | FOR of {name:Id.T} * (Typ.T list) * T fun debruijnify te (PREVAR i) = VAR((), index te i) | debruijnify te (PREABS(i,ptyp,ptrm)) = ABS({name=i}, Typ.debruijnify te ptyp, debruijnify (push_binding te i NS) ptrm) | debruijnify te (PREAPP(ptrm1,ptrm2)) = APP((), debruijnify te ptrm1, debruijnify te ptrm2) | debruijnify te (PRETABS(i,ptyp,ptrm)) = TABS({name=i}, Typ.debruijnify te ptyp, debruijnify (push_bound te i NS) ptrm) | debruijnify te (PRETAPP(ptrm,ptyp)) = TAPP((), debruijnify te ptrm, Typ.debruijnify te ptyp) | debruijnify te (PREFOR(i,ptyps,ptrm)) = FOR({name=i}, map (fn pt => Typ.debruijnify te pt) ptyps, debruijnify (push_bound te i NS) ptrm) fun prt pp te trm = let fun p te (VAR(_,i)) = Pp.pwrite pp (Id.tostr (lookup_name te i)) | p te (ABS({name=i},t,body)) = (Pp.pwrite pp "(\\"; Pp.pwrite pp (Id.tostr i); Pp.pwrite pp ":"; Typ.prt pp te t; Pp.pwrite pp ". "; p (push_binding te i t) body; Pp.pwrite pp ")") | p te (APP(_,trm1,trm2)) = (Pp.pwrite pp "("; p te trm1; Pp.pwrite pp " "; p te trm2; Pp.pwrite pp ")") | p te (TABS({name=i},t,body)) = (Pp.pwrite pp "(\\\\"; Pp.pwrite pp (Id.tostr i); Pp.pwrite pp "<="; Typ.prt pp te t; Pp.pwrite pp ". "; p (push_bound te i t) body; Pp.pwrite pp ")") | p te (TAPP(_,trm1,t)) = (Pp.pwrite pp "("; p te trm1; Pp.pwrite pp " ["; Typ.prt pp te t; Pp.pwrite pp "])") | p te (FOR({name=i},ts,body)) = (Pp.pwrite pp "(for "; Pp.pwrite pp (Id.tostr i); Pp.pwrite pp " in "; mapunit_tuple (fn t => Typ.prt pp te t) (fn () => Pp.pwrite pp ",") ts; Pp.pwrite pp ". "; p (push_abbrev te i NS) body; Pp.pwrite pp ")") in p te trm end end functor ListUtils() : LISTUTILS = struct fun mapunit f l = let fun mu [] = () | mu (hd::tl) = (f hd; mu tl) in mu l end fun mapunit_tuple f betw ts = let fun mut [] = () | mut [e] = f e | mut (e::tl) = (f e; betw(); mut tl) in mut ts end fun mapfold fm ff z = let fun m [] = z | m (hd::tl) = ff (fm hd) (m tl) in m end fun memq eq l e = let fun m [] = false | m (hd::tl) = (eq e hd) orelse (m tl) in m l end fun mapappend f l = let fun ma [] = [] | ma (hd::tl) = (f hd) @ (ma tl) in ma l end fun filter b l = let fun f [] = [] | f (hd::tl) = if (b hd) then hd::(f tl) else f tl in f l end fun forall f = mapfold f (fn x => fn y => x andalso y) true fun forsome f = mapfold f (fn x => fn y => x orelse y) false end functor Synth( structure Globals: GLOBALS structure Typ: TYPPVT structure Trm: TRMPVT structure Leq: LEQ sharing Typ.Globals = Globals and Trm.Typ = Typ and Leq.Typ = Typ ) : SYNTH = struct structure Globals = Globals structure Typ = Typ structure Trm = Trm structure Leq = Leq open Globals open Typ open Trm val DEBUG = ref(false) val _ = (registerflag "synth" DEBUG; registerflag "Synth" DEBUG) fun arrowbasis te t = let fun ab (TVAR(_,v)) = (case lookup_and_relocate te v of BND(_,b) => ab b | VBND(n,b) => raise Typ.WrongKindOfId(te,v,"tvar or abbrev") | ABB(_,b) => ab b) | ab (t as ARROW(_)) = [t] | ab (ALL(_)) = [] | ab (MEET(_,ts)) = mapappend ab ts in ab t end fun allbasis te t = let fun ab (TVAR(_,v)) = (case lookup_and_relocate te v of BND(_,b) => ab b | VBND(n,b) => raise Typ.WrongKindOfId(te,v,"tvar or abbrev") | ABB(_,b) => ab b) | ab (t as ARROW(_)) = [] | ab (t as ALL(_)) = [t] | ab (MEET(_,ts)) = mapappend ab ts in ab t end fun synth' te (VAR(_,v)) = Typ.lookup_and_relocate_binding te v | synth' te (ABS({name=i},t,body)) = let val t_body = synth (push_binding te i t) body val t' = relocate ~1 t_body in ARROW((),t,t') end | synth' te (APP(_,trm1,trm2)) = let val t1 = synth te trm1 and t2 = synth te trm2 val basis = arrowbasis te t1 fun collect_apps [] = [] | collect_apps ((ARROW(_,tb1,tb2))::tl) = if Leq.leq te t2 tb1 then tb2::(collect_apps tl) else (collect_apps tl) | collect_apps _ = raise CantHappen val ts = collect_apps basis in MEET((),ts) end | synth' te (TABS({name=i},t,body)) = let val t' = synth (push_bound te i t) body in ALL({name=i},t,t') end | synth' te (TAPP(_,body,t)) = let val t_body = synth te body val basis = allbasis te t_body fun collect_apps [] = [] | collect_apps ((ALL(_,t1,t2))::tl) = if Leq.leq te t t1 then (tsubst_top t t2)::(collect_apps tl) else (collect_apps tl) | collect_apps _ = raise CantHappen val ts = collect_apps basis in MEET((),ts) end | synth' te (FOR({name=i},ts,body)) = let fun f t = let val tb = synth (push_abbrev te i t) body val tb' = tsubst_top t tb in tb' end in MEET((), map f ts) end and synth te e = wrap (DEBUG) "synth" (fn () => synth' te e) (fn () => (Trm.prt (stdpp()) te e; Pp.pwrite (stdpp()) "\n"; Typ.prt_tenv (stdpp()) te)) (fn t => (Typ.prt (stdpp()) te t)) end functor FMEETLrValsFun ( structure Token : TOKEN structure Globals : GLOBALS structure ParseRes : PARSERES ) : FMEET_LRVALS = struct structure ParserData= struct structure Header = struct structure ParseRes = ParseRes open ParseRes open Trm open Typ open Globals end structure LrTable = Token.LrTable structure Token = Token local open LrTable in val table=let val actionT = "\ \\001\000\022\000\014\000\021\000\023\000\020\000\ \\024\000\019\000\025\000\018\000\026\000\017\000\027\000\016\000\ \\028\000\015\000\029\000\014\000\030\000\013\000\031\000\012\000\ \\032\000\011\000\033\000\010\000\040\000\009\000\000\000\001\000\ \\000\000\141\000\ \\014\000\025\000\016\000\024\000\025\000\018\000\000\000\140\000\ \\000\000\116\000\ \\000\000\147\000\ \\005\000\028\000\008\000\027\000\009\000\026\000\000\000\137\000\ \\000\000\118\000\ \\025\000\018\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\025\000\038\000\000\000\001\000\ \\025\000\039\000\000\000\001\000\ \\025\000\040\000\000\000\001\000\ \\025\000\018\000\000\000\001\000\ \\025\000\042\000\000\000\001\000\ \\000\000\139\000\ \\000\000\138\000\ \\000\000\136\000\ \\025\000\018\000\000\000\001\000\ \\025\000\018\000\000\000\001\000\ \\014\000\021\000\023\000\020\000\024\000\019\000\ \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\ \\000\000\117\000\ \\000\000\149\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\021\000\023\000\020\000\024\000\019\000\ \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\021\000\023\000\020\000\024\000\019\000\ \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\036\000\053\000\000\000\001\000\ \\006\000\054\000\000\000\134\000\ \\005\000\057\000\012\000\056\000\022\000\055\000\000\000\001\000\ \\000\000\122\000\ \\025\000\018\000\000\000\001\000\ \\000\000\126\000\ \\025\000\018\000\000\000\001\000\ \\016\000\060\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\000\000\120\000\ \\000\000\121\000\ \\000\000\119\000\ \\005\000\063\000\009\000\062\000\000\000\001\000\ \\000\000\110\000\ \\036\000\064\000\000\000\001\000\ \\002\000\066\000\005\000\065\000\006\000\054\000\000\000\134\000\ \\003\000\067\000\000\000\001\000\ \\015\000\068\000\000\000\001\000\ \\000\000\137\000\ \\012\000\056\000\017\000\069\000\022\000\055\000\000\000\001\000\ \\015\000\070\000\000\000\001\000\ \\012\000\056\000\022\000\055\000\000\000\114\000\ \\000\000\115\000\ \\012\000\056\000\022\000\055\000\000\000\112\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\025\000\018\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\002\000\078\000\005\000\077\000\000\000\001\000\ \\002\000\080\000\005\000\079\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\012\000\056\000\015\000\082\000\022\000\055\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\021\000\023\000\020\000\024\000\019\000\ \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\000\000\148\000\ \\000\000\151\000\ \\000\000\150\000\ \\002\000\089\000\000\000\001\000\ \\006\000\090\000\012\000\056\000\022\000\055\000\000\000\132\000\ \\000\000\135\000\ \\012\000\056\000\022\000\055\000\000\000\124\000\ \\012\000\056\000\000\000\123\000\ \\012\000\056\000\022\000\055\000\000\000\109\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\017\000\095\000\000\000\001\000\ \\000\000\127\000\ \\012\000\056\000\022\000\055\000\000\000\113\000\ \\012\000\056\000\022\000\055\000\000\000\111\000\ \\002\000\096\000\000\000\001\000\ \\002\000\097\000\012\000\056\000\022\000\055\000\000\000\001\000\ \\000\000\143\000\ \\002\000\098\000\000\000\001\000\ \\014\000\021\000\023\000\020\000\024\000\019\000\ \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\002\000\101\000\012\000\056\000\022\000\055\000\000\000\001\000\ \\012\000\056\000\022\000\055\000\000\000\130\000\ \\002\000\102\000\012\000\056\000\022\000\055\000\000\000\001\000\ \\012\000\056\000\022\000\055\000\000\000\128\000\ \\000\000\125\000\ \\014\000\021\000\023\000\020\000\024\000\019\000\ \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\ \\014\000\021\000\023\000\020\000\024\000\019\000\ \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\ \\014\000\021\000\023\000\020\000\024\000\019\000\ \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\ \\000\000\146\000\ \\000\000\133\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\014\000\037\000\022\000\036\000\025\000\018\000\ \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\ \\000\000\145\000\ \\000\000\144\000\ \\000\000\142\000\ \\012\000\056\000\022\000\055\000\000\000\131\000\ \\012\000\056\000\022\000\055\000\000\000\129\000\ \\001\000\000\000\004\000\000\000\000\000\001\000\ \" val gotoT = "\ \\001\000\106\000\002\000\006\000\003\000\005\000\ \\005\000\004\000\008\000\003\000\009\000\002\000\010\000\001\000\000\000\000\000\ \\000\000\000\000\ \\003\000\021\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\028\000\004\000\027\000\000\000\000\000\ \\003\000\030\000\006\000\029\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\039\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\042\000\004\000\041\000\000\000\000\000\ \\003\000\043\000\000\000\000\000\ \\003\000\045\000\005\000\004\000\008\000\044\000\ \\009\000\002\000\010\000\001\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\030\000\006\000\046\000\000\000\000\000\ \\003\000\045\000\005\000\004\000\008\000\047\000\ \\009\000\002\000\010\000\001\000\000\000\000\000\ \\003\000\030\000\006\000\048\000\000\000\000\000\ \\003\000\045\000\005\000\004\000\008\000\049\000\ \\009\000\002\000\010\000\001\000\000\000\000\000\ \\003\000\030\000\006\000\050\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\056\000\000\000\000\000\ \\000\000\000\000\ \\003\000\057\000\000\000\000\000\ \\000\000\000\000\ \\003\000\030\000\006\000\059\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\030\000\006\000\070\000\007\000\069\000\000\000\000\000\ \\003\000\028\000\004\000\071\000\000\000\000\000\ \\003\000\030\000\006\000\072\000\000\000\000\000\ \\003\000\030\000\006\000\073\000\000\000\000\000\ \\003\000\030\000\006\000\074\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\030\000\006\000\070\000\007\000\079\000\000\000\000\000\ \\000\000\000\000\ \\003\000\030\000\006\000\081\000\000\000\000\000\ \\003\000\030\000\006\000\082\000\000\000\000\000\ \\003\000\030\000\006\000\070\000\007\000\083\000\000\000\000\000\ \\003\000\030\000\006\000\084\000\000\000\000\000\ \\003\000\045\000\005\000\004\000\008\000\085\000\ \\009\000\002\000\010\000\001\000\000\000\000\000\ \\003\000\030\000\006\000\070\000\007\000\086\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\030\000\006\000\089\000\000\000\000\000\ \\003\000\030\000\006\000\090\000\000\000\000\000\ \\003\000\030\000\006\000\091\000\000\000\000\000\ \\003\000\030\000\006\000\092\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\045\000\005\000\004\000\008\000\097\000\ \\009\000\002\000\010\000\001\000\000\000\000\000\ \\003\000\030\000\006\000\070\000\007\000\098\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\045\000\005\000\004\000\008\000\101\000\ \\009\000\002\000\010\000\001\000\000\000\000\000\ \\003\000\045\000\005\000\004\000\008\000\102\000\ \\009\000\002\000\010\000\001\000\000\000\000\000\ \\003\000\045\000\005\000\004\000\008\000\103\000\ \\009\000\002\000\010\000\001\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\003\000\030\000\006\000\104\000\000\000\000\000\ \\003\000\030\000\006\000\105\000\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \\000\000\000\000\ \" val numstates = 107 val string_to_int = fn(s,index) => (ordof(s,index) + ordof(s,index+1)*256,index+2) val convert_string_to_row = fn (conv_key,conv_entry) => fn(s,index) => let fun f (r,index) = let val (num,index) = string_to_int(s,index) val (i,index) = string_to_int(s,index) in if num=0 then ((rev r,conv_entry i),index) else f((conv_key (num-1),conv_entry i)::r,index) end in f(nil,index) end val convert_string_to_row_list = fn conv_funcs => fn s => let val convert_row =convert_string_to_row conv_funcs fun f(r,index) = if index < String.length s then let val (newlist,index) = convert_row (s,index) in f(newlist::r,index) end else rev r in f(nil,0) end val entry_to_action = fn j => if j=0 then ACCEPT else if j=1 then ERROR else if j >= (numstates+2) then REDUCE (j-numstates-2) else SHIFT (STATE (j-2)) val make_goto_table = convert_string_to_row_list(NT,STATE) val make_action_table=convert_string_to_row_list(T,entry_to_action) val gotoT = map (fn (a,b) => a) (make_goto_table gotoT) val actionT = make_action_table actionT in LrTable.mkLrTable {actions=actionT,gotos=gotoT, numStates=numstates,initialState=STATE 0} end end local open Header in type pos = int type arg = unit structure MlyValue = struct datatype svalue = VOID | ntVOID of unit | T_STR_CONST of (string) | T_INT_CONST of (string) | T_ID of (string) | bnd of (ParseRes.Trm.pretrm) | appl of (ParseRes.Trm.pretrm) | term of (ParseRes.Trm.pretrm) | tplist of (ParseRes.Typ.pretyp list) | tp of (ParseRes.Typ.pretyp) | const of (Id.T) | idlist of (Id.T list) | id of (Id.T) | setcmd of (ParseRes.T) | start of (ParseRes.T) end type svalue = MlyValue.svalue type result = ParseRes.T end structure EC= struct open LrTable val is_keyword = fn _ => false val preferred_insert = fn (T 1) => true | (T 38) => true | _ => false val preferred_subst = fn _ => nil val noShift = fn (T 3) => true | (T 0) => true | _ => false val showTerminal = fn (T 0) => "T_EOF" | (T 1) => "T_DOT" | (T 2) => "T_COLON" | (T 3) => "T_SEMICOLON" | (T 4) => "T_LEQ" | (T 5) => "T_COMMA" | (T 6) => "T_APOST" | (T 7) => "T_EQ" | (T 8) => "T_DOUBLEEQ" | (T 9) => "T_DOLLAR" | (T 10) => "T_AT" | (T 11) => "T_ARROW" | (T 12) => "T_DARROW" | (T 13) => "T_LPAREN" | (T 14) => "T_RPAREN" | (T 15) => "T_LBRACK" | (T 16) => "T_RBRACK" | (T 17) => "T_LANGLE" | (T 18) => "T_RANGLE" | (T 19) => "T_LCURLY" | (T 20) => "T_RCURLY" | (T 21) => "T_INTER" | (T 22) => "T_LAMBDA" | (T 23) => "T_BIGLAMBDA" | (T 24) => "T_ID" | (T 25) => "T_INT_CONST" | (T 26) => "T_STR_CONST" | (T 27) => "T_USE" | (T 28) => "T_TYPE" | (T 29) => "T_SET" | (T 30) => "T_RESET" | (T 31) => "T_DEBUG" | (T 32) => "T_CHECK" | (T 33) => "T_WITH" | (T 34) => "T_ALL" | (T 35) => "T_IN" | (T 36) => "T_NS" | (T 37) => "T_CASE" | (T 38) => "T_OF" | (T 39) => "T_FOR" | (T 40) => "T_OBSERVE" | (T 41) => "T_INSTALL" | (T 42) => "T_SOME" | (T 43) => "T_OPEN" | (T 44) => "T_END" | (T 45) => "T_PACK" | _ => "bogus-term" val errtermvalue= let open Header in fn _ => MlyValue.VOID end val terms = (T 0) :: (T 1) :: (T 2) :: (T 3) :: (T 4) :: (T 5) :: (T 6 ) :: (T 7) :: (T 8) :: (T 9) :: (T 10) :: (T 11) :: (T 12) :: (T 13) :: (T 14) :: (T 15) :: (T 16) :: (T 17) :: (T 18) :: (T 19) :: (T 20) :: (T 21) :: (T 22) :: (T 23) :: (T 27) :: (T 28) :: (T 29) :: (T 30) :: (T 31) :: (T 32) :: (T 33) :: (T 34) :: (T 35) :: (T 36) :: (T 37) :: (T 38) :: (T 39) :: (T 40) :: (T 41) :: (T 42) :: (T 43) :: (T 44) :: (T 45) :: nil end structure Actions = struct exception mlyAction of int val actions = let open Header in fn (i392,defaultPos,stack, (()):arg) => case (i392,stack) of (0,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_,T_LEQleft as T_LEQ1left,T_LEQright as T_LEQ1right)) :: (_,(MlyValue.tp (tp1 as tp), tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_CHECKleft as T_CHECK1left,T_CHECKright as T_CHECK1right)) :: rest671) => let val result = MlyValue.start (((Leq(tp1,tp2)))) in (LrTable.NT 0,(result,T_CHECK1left,tp2right),rest671) end | (1,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left, T_IDright as T_ID1right)) :: (_,(_,T_USEleft as T_USE1left, T_USEright as T_USE1right)) :: rest671) => let val result = MlyValue.start (((Use(T_ID)))) in (LrTable.NT 0,(result,T_USE1left,T_ID1right),rest671) end | (2,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right )) :: (_,(_,T_LEQleft as T_LEQ1left,T_LEQright as T_LEQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right )) :: (_,(_,T_TYPEleft as T_TYPE1left,T_TYPEright as T_TYPE1right )) :: rest671) => let val result = MlyValue.start (((Type_Assumption(id,tp)))) in (LrTable.NT 0,(result,T_TYPE1left,tp1right),rest671) end | (3,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right )) :: (_,(_,T_LEQleft as T_LEQ1left,T_LEQright as T_LEQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right )) :: rest671) => let val result = MlyValue.start (((Type_Assumption(id,tp)))) in (LrTable.NT 0,(result,id1left,tp1right),rest671) end | (4,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right )) :: (_,(_,T_DOUBLEEQleft as T_DOUBLEEQ1left,T_DOUBLEEQright as T_DOUBLEEQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left, idright as id1right)) :: (_,(_,T_TYPEleft as T_TYPE1left, T_TYPEright as T_TYPE1right)) :: rest671) => let val result = MlyValue.start (((Type_Abbrev(id,tp)))) in (LrTable.NT 0,(result,T_TYPE1left,tp1right),rest671) end | (5,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right )) :: (_,(_,T_DOUBLEEQleft as T_DOUBLEEQ1left,T_DOUBLEEQright as T_DOUBLEEQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left, idright as id1right)) :: rest671) => let val result = MlyValue.start (((Type_Abbrev(id,tp)))) in (LrTable.NT 0,(result,id1left,tp1right),rest671) end | (6,(_,(MlyValue.term (term1 as term),termleft as term1left, termright as term1right)) :: (_,(_,T_EQleft as T_EQ1left,T_EQright as T_EQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left, idright as id1right)) :: rest671) => let val result = MlyValue.start (((Term_Def(id,term)))) in (LrTable.NT 0,(result,id1left,term1right),rest671) end | (7,(_,(MlyValue.term (term1 as term),termleft as term1left, termright as term1right)) :: rest671) => let val result = MlyValue.start (((Term_Def(Id.intern "it",term)))) in (LrTable.NT 0,(result,term1left,term1right),rest671) end | (8,(_,(_,T_EOFleft as T_EOF1left,T_EOFright as T_EOF1right)) :: rest671) => let val result = MlyValue.start (((Nothing))) in (LrTable.NT 0,(result,T_EOF1left,T_EOF1right),rest671) end | (9,(_,(MlyValue.setcmd (setcmd1 as setcmd),setcmdleft as setcmd1left ,setcmdright as setcmd1right)) :: rest671) => let val result = MlyValue.start (((setcmd))) in (LrTable.NT 0,(result,setcmd1left,setcmd1right),rest671) end | (10,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left, T_IDright as T_ID1right)) :: (_,(_,T_SETleft as T_SET1left, T_SETright as T_SET1right)) :: rest671) => let val result = MlyValue.setcmd (((Set(T_ID,"true")))) in (LrTable.NT 1,(result,T_SET1left,T_ID1right),rest671) end | (11,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left, T_IDright as T_ID1right)) :: (_,(_,T_DEBUGleft as T_DEBUG1left, T_DEBUGright as T_DEBUG1right)) :: rest671) => let val result = MlyValue.setcmd (((Set(T_ID,"true")))) in (LrTable.NT 1,(result,T_DEBUG1left,T_ID1right),rest671) end | (12,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left, T_IDright as T_ID1right)) :: (_,(_,T_RESETleft as T_RESET1left, T_RESETright as T_RESET1right)) :: rest671) => let val result = MlyValue.setcmd (((Set(T_ID,"false")))) in (LrTable.NT 1,(result,T_RESET1left,T_ID1right),rest671) end | (13,(_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: rest671) => let val result = MlyValue.tp (((PRETVAR(id)))) in (LrTable.NT 5,(result,id1left,id1right),rest671) end | (14,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_, T_ARROWleft as T_ARROW1left,T_ARROWright as T_ARROW1right)) :: (_,( MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: rest671) => let val result = MlyValue.tp (((PREARROW(tp1,tp2)))) in (LrTable.NT 5,(result,tp1left,tp2right),rest671) end | (15,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_, T_INTERleft as T_INTER1left,T_INTERright as T_INTER1right)) :: (_,( MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: rest671) => let val result = MlyValue.tp (((PREMEET([tp1,tp2])))) in (LrTable.NT 5,(result,tp1left,tp2right),rest671) end | (16,(_,(_,T_RBRACKleft as T_RBRACK1left,T_RBRACKright as T_RBRACK1right)) :: (_,(MlyValue.tplist (tplist1 as tplist), tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_, T_LBRACKleft as T_LBRACK1left,T_LBRACKright as T_LBRACK1right)) :: (_,(_,T_INTERleft as T_INTER1left,T_INTERright as T_INTER1right)) :: rest671) => let val result = MlyValue.tp (((PREMEET(tplist)))) in (LrTable.NT 5,(result,T_INTER1left,T_RBRACK1right),rest671) end | (17,(_,(_,T_NSleft as T_NS1left,T_NSright as T_NS1right)) :: rest671) => let val result = MlyValue.tp (((PREMEET([])))) in (LrTable.NT 5,(result,T_NS1left,T_NS1right),rest671) end | (18,(_,(_,T_RPARENleft as T_RPAREN1left,T_RPARENright as T_RPAREN1right)) :: (_,(MlyValue.tp (tp1 as tp),tpleft as tp1left, tpright as tp1right)) :: (_,(_,T_LPARENleft as T_LPAREN1left, T_LPARENright as T_LPAREN1right)) :: rest671) => let val result = MlyValue.tp (((tp))) in (LrTable.NT 5,(result,T_LPAREN1left,T_RPAREN1right),rest671) end | (19,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_DOTleft as T_DOT1left,T_DOTright as T_DOT1right )) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: (_,(_,T_ALLleft as T_ALL1left,T_ALLright as T_ALL1right )) :: rest671) => let val result = MlyValue.tp (((PREALL(id, PREMEET[], tp)))) in (LrTable.NT 5,(result,T_ALL1left,tp1right),rest671) end | (20,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_,T_DOTleft as T_DOT1left,T_DOTright as T_DOT1right)) :: (_,(MlyValue.tp (tp1 as tp), tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_LEQleft as T_LEQ1left,T_LEQright as T_LEQ1right)) :: (_,(MlyValue.id (id1 as id), idleft as id1left,idright as id1right)) :: (_,(_,T_ALLleft as T_ALL1left,T_ALLright as T_ALL1right)) :: rest671) => let val result = MlyValue.tp (((PREALL(id, tp1, tp2)))) in (LrTable.NT 5,(result,T_ALL1left,tp2right),rest671) end | (21,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_DOTleft as T_DOT1left,T_DOTright as T_DOT1right )) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: (_,(_,T_SOMEleft as T_SOME1left,T_SOMEright as T_SOME1right)) :: rest671) => let val result = MlyValue.tp ((( let val b = Id.new() val bv = PRETVAR(b) val idv = PRETVAR(id) in PREALL(b,PREMEET[], PREARROW(PREALL(id, PREMEET[], PREARROW(tp, bv)), bv)) end ))) in (LrTable.NT 5,(result,T_SOME1left,tp1right),rest671) end | (22,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_,T_DOTleft as T_DOT1left,T_DOTright as T_DOT1right)) :: (_,(MlyValue.tp (tp1 as tp), tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_LEQleft as T_LEQ1left,T_LEQright as T_LEQ1right)) :: (_,(MlyValue.id (id1 as id), idleft as id1left,idright as id1right)) :: (_,(_,T_SOMEleft as T_SOME1left,T_SOMEright as T_SOME1right)) :: rest671) => let val result = MlyValue.tp ((( let val b = Id.new() val bv = PRETVAR(b) val idv = PRETVAR(id) in PREALL(b,PREMEET[], PREARROW(PREALL(id, tp1, PREARROW(tp2, bv)), bv)) end ))) in (LrTable.NT 5,(result,T_SOME1left,tp2right),rest671) end | (23,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: rest671) => let val result = MlyValue.tplist ((([tp]))) in (LrTable.NT 6,(result,tp1left,tp1right),rest671) end | (24,(_,(MlyValue.tplist (tplist1 as tplist),tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_,T_COMMAleft as T_COMMA1left,T_COMMAright as T_COMMA1right)) :: (_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: rest671) => let val result = MlyValue.tplist (((tp::tplist))) in (LrTable.NT 6,(result,tp1left,tplist1right),rest671) end | (25,(_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: rest671) => let val result = MlyValue.idlist ((([id]))) in (LrTable.NT 3,(result,id1left,id1right),rest671) end | (26,(_,(MlyValue.idlist (idlist1 as idlist),idlistleft as idlist1left,idlistright as idlist1right)) :: (_,(_,T_COMMAleft as T_COMMA1left,T_COMMAright as T_COMMA1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: rest671) => let val result = MlyValue.idlist (((id::idlist))) in (LrTable.NT 3,(result,id1left,idlist1right),rest671) end | (27,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left, T_IDright as T_ID1right)) :: rest671) => let val result = MlyValue.id (((Id.intern T_ID))) in (LrTable.NT 2,(result,T_ID1left,T_ID1right),rest671) end | (28,(_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: rest671) => let val result = MlyValue.const (((id))) in (LrTable.NT 4,(result,id1left,id1right),rest671) end | (29,(_,(MlyValue.T_INT_CONST (T_INT_CONST1 as T_INT_CONST), T_INT_CONSTleft as T_INT_CONST1left,T_INT_CONSTright as T_INT_CONST1right)) :: rest671) => let val result = MlyValue.const (((Id.intern T_INT_CONST))) in (LrTable.NT 4,(result,T_INT_CONST1left,T_INT_CONST1right),rest671) end | (30,(_,(MlyValue.T_STR_CONST (T_STR_CONST1 as T_STR_CONST), T_STR_CONSTleft as T_STR_CONST1left,T_STR_CONSTright as T_STR_CONST1right)) :: rest671) => let val result = MlyValue.const (((Id.intern T_STR_CONST))) in (LrTable.NT 4,(result,T_STR_CONST1left,T_STR_CONST1right),rest671) end | (31,(_,(MlyValue.appl (appl1 as appl),applleft as appl1left, applright as appl1right)) :: rest671) => let val result = MlyValue.term (((appl))) in (LrTable.NT 7,(result,appl1left,appl1right),rest671) end | (32,(_,(MlyValue.bnd (bnd1 as bnd),bndleft as bnd1left,bndright as bnd1right)) :: rest671) => let val result = MlyValue.term (((bnd))) in (LrTable.NT 7,(result,bnd1left,bnd1right),rest671) end | (33,(_,(MlyValue.term (term1 as term),termleft as term1left, termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left, T_DOTright as T_DOT1right)) :: (_,(MlyValue.tplist (tplist1 as tplist) ,tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_, T_COLONleft as T_COLON1left,T_COLONright as T_COLON1right)) :: (_,( MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: (_,(_,T_LAMBDAleft as T_LAMBDA1left,T_LAMBDAright as T_LAMBDA1right )) :: rest671) => let val result = MlyValue.bnd ((( case tplist of [t] => PREABS(id,t,term) | ts => let val a = Id.new_from id in PREFOR(a,ts, PREABS(id,PRETVAR(a),term)) end ))) in (LrTable.NT 9,(result,T_LAMBDA1left,term1right),rest671) end | (34,(_,(MlyValue.term (term1 as term),termleft as term1left, termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left, T_DOTright as T_DOT1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: (_,(_,T_BIGLAMBDAleft as T_BIGLAMBDA1left,T_BIGLAMBDAright as T_BIGLAMBDA1right)) :: rest671) => let val result = MlyValue.bnd (((PRETABS(id,PREMEET[],term)))) in (LrTable.NT 9,(result,T_BIGLAMBDA1left,term1right),rest671) end | (35,(_,(MlyValue.term (term1 as term),termleft as term1left, termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left, T_DOTright as T_DOT1right)) :: (_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_LEQleft as T_LEQ1left, T_LEQright as T_LEQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: (_,(_,T_BIGLAMBDAleft as T_BIGLAMBDA1left,T_BIGLAMBDAright as T_BIGLAMBDA1right)) :: rest671) => let val result = MlyValue.bnd (((PRETABS(id,tp,term)))) in (LrTable.NT 9,(result,T_BIGLAMBDA1left,term1right),rest671) end | (36,(_,(MlyValue.term (term1 as term),termleft as term1left, termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left, T_DOTright as T_DOT1right)) :: (_,(MlyValue.tplist (tplist1 as tplist) ,tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_, T_INleft as T_IN1left,T_INright as T_IN1right)) :: (_,(MlyValue.idlist (idlist1 as idlist),idlistleft as idlist1left,idlistright as idlist1right)) :: (_,(_,T_BIGLAMBDAleft as T_BIGLAMBDA1left, T_BIGLAMBDAright as T_BIGLAMBDA1right)) :: rest671) => let val result = MlyValue.bnd ((( let fun f [] = term | f (v::vs) = PREFOR(v, tplist, f vs) in f idlist end ))) in (LrTable.NT 9,(result,T_BIGLAMBDA1left,term1right),rest671) end | (37,(_,(MlyValue.term (term1 as term),termleft as term1left, termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left, T_DOTright as T_DOT1right)) :: (_,(MlyValue.tplist (tplist1 as tplist) ,tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_, T_INleft as T_IN1left,T_INright as T_IN1right)) :: (_,(MlyValue.idlist (idlist1 as idlist),idlistleft as idlist1left,idlistright as idlist1right)) :: (_,(_,T_FORleft as T_FOR1left,T_FORright as T_FOR1right)) :: rest671) => let val result = MlyValue.bnd ((( let fun f [] = term | f (v::vs) = PREFOR(v, tplist, f vs) in f idlist end ))) in (LrTable.NT 9,(result,T_FOR1left,term1right),rest671) end | (38,(_,(MlyValue.const (const1 as const),constleft as const1left, constright as const1right)) :: rest671) => let val result = MlyValue.appl (((PREVAR(const)))) in (LrTable.NT 8,(result,const1left,const1right),rest671) end | (39,(_,(_,T_RPARENleft as T_RPAREN1left,T_RPARENright as T_RPAREN1right)) :: (_,(MlyValue.term (term1 as term),termleft as term1left,termright as term1right)) :: (_,(_,T_LPARENleft as T_LPAREN1left,T_LPARENright as T_LPAREN1right)) :: rest671) => let val result = MlyValue.appl (((term))) in (LrTable.NT 8,(result,T_LPAREN1left,T_RPAREN1right),rest671) end | (40,(_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: (_,(MlyValue.appl (appl1 as appl),applleft as appl1left, applright as appl1right)) :: rest671) => let val result = MlyValue.appl (((PREAPP(appl,PREVAR(id))))) in (LrTable.NT 8,(result,appl1left,id1right),rest671) end | (41,(_,(_,T_RPARENleft as T_RPAREN1left,T_RPARENright as T_RPAREN1right)) :: (_,(MlyValue.term (term1 as term),termleft as term1left,termright as term1right)) :: (_,(_,T_LPARENleft as T_LPAREN1left,T_LPARENright as T_LPAREN1right)) :: (_,(MlyValue.appl ( appl1 as appl),applleft as appl1left,applright as appl1right)) :: rest671) => let val result = MlyValue.appl (((PREAPP(appl,term)))) in (LrTable.NT 8,(result,appl1left,T_RPAREN1right),rest671) end | (42,(_,(_,T_RBRACKleft as T_RBRACK1left,T_RBRACKright as T_RBRACK1right)) :: (_,(MlyValue.tp (tp1 as tp),tpleft as tp1left, tpright as tp1right)) :: (_,(_,T_LBRACKleft as T_LBRACK1left, T_LBRACKright as T_LBRACK1right)) :: (_,(MlyValue.appl (appl1 as appl) ,applleft as appl1left,applright as appl1right)) :: rest671) => let val result = MlyValue.appl (((PRETAPP(appl,tp)))) in (LrTable.NT 8,(result,appl1left,T_RBRACK1right),rest671) end | _ => raise (mlyAction i392) end val void = MlyValue.VOID val extract = fn a => (fn MlyValue.start x => x | _ => let exception ParseInternal in raise ParseInternal end) a end end structure Tokens : FMEET_TOKENS = struct type svalue = ParserData.svalue type ('a,'b) token = ('a,'b) Token.token fun T_EOF (p1,p2) = Token.TOKEN (ParserData.LrTable.T 0,( ParserData.MlyValue.VOID,p1,p2)) fun T_DOT (p1,p2) = Token.TOKEN (ParserData.LrTable.T 1,( ParserData.MlyValue.VOID,p1,p2)) fun T_COLON (p1,p2) = Token.TOKEN (ParserData.LrTable.T 2,( ParserData.MlyValue.VOID,p1,p2)) fun T_SEMICOLON (p1,p2) = Token.TOKEN (ParserData.LrTable.T 3,( ParserData.MlyValue.VOID,p1,p2)) fun T_LEQ (p1,p2) = Token.TOKEN (ParserData.LrTable.T 4,( ParserData.MlyValue.VOID,p1,p2)) fun T_COMMA (p1,p2) = Token.TOKEN (ParserData.LrTable.T 5,( ParserData.MlyValue.VOID,p1,p2)) fun T_APOST (p1,p2) = Token.TOKEN (ParserData.LrTable.T 6,( ParserData.MlyValue.VOID,p1,p2)) fun T_EQ (p1,p2) = Token.TOKEN (ParserData.LrTable.T 7,( ParserData.MlyValue.VOID,p1,p2)) fun T_DOUBLEEQ (p1,p2) = Token.TOKEN (ParserData.LrTable.T 8,( ParserData.MlyValue.VOID,p1,p2)) fun T_DOLLAR (p1,p2) = Token.TOKEN (ParserData.LrTable.T 9,( ParserData.MlyValue.VOID,p1,p2)) fun T_AT (p1,p2) = Token.TOKEN (ParserData.LrTable.T 10,( ParserData.MlyValue.VOID,p1,p2)) fun T_ARROW (p1,p2) = Token.TOKEN (ParserData.LrTable.T 11,( ParserData.MlyValue.VOID,p1,p2)) fun T_DARROW (p1,p2) = Token.TOKEN (ParserData.LrTable.T 12,( ParserData.MlyValue.VOID,p1,p2)) fun T_LPAREN (p1,p2) = Token.TOKEN (ParserData.LrTable.T 13,( ParserData.MlyValue.VOID,p1,p2)) fun T_RPAREN (p1,p2) = Token.TOKEN (ParserData.LrTable.T 14,( ParserData.MlyValue.VOID,p1,p2)) fun T_LBRACK (p1,p2) = Token.TOKEN (ParserData.LrTable.T 15,( ParserData.MlyValue.VOID,p1,p2)) fun T_RBRACK (p1,p2) = Token.TOKEN (ParserData.LrTable.T 16,( ParserData.MlyValue.VOID,p1,p2)) fun T_LANGLE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 17,( ParserData.MlyValue.VOID,p1,p2)) fun T_RANGLE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 18,( ParserData.MlyValue.VOID,p1,p2)) fun T_LCURLY (p1,p2) = Token.TOKEN (ParserData.LrTable.T 19,( ParserData.MlyValue.VOID,p1,p2)) fun T_RCURLY (p1,p2) = Token.TOKEN (ParserData.LrTable.T 20,( ParserData.MlyValue.VOID,p1,p2)) fun T_INTER (p1,p2) = Token.TOKEN (ParserData.LrTable.T 21,( ParserData.MlyValue.VOID,p1,p2)) fun T_LAMBDA (p1,p2) = Token.TOKEN (ParserData.LrTable.T 22,( ParserData.MlyValue.VOID,p1,p2)) fun T_BIGLAMBDA (p1,p2) = Token.TOKEN (ParserData.LrTable.T 23,( ParserData.MlyValue.VOID,p1,p2)) fun T_ID (i,p1,p2) = Token.TOKEN (ParserData.LrTable.T 24,( ParserData.MlyValue.T_ID i,p1,p2)) fun T_INT_CONST (i,p1,p2) = Token.TOKEN (ParserData.LrTable.T 25,( ParserData.MlyValue.T_INT_CONST i,p1,p2)) fun T_STR_CONST (i,p1,p2) = Token.TOKEN (ParserData.LrTable.T 26,( ParserData.MlyValue.T_STR_CONST i,p1,p2)) fun T_USE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 27,( ParserData.MlyValue.VOID,p1,p2)) fun T_TYPE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 28,( ParserData.MlyValue.VOID,p1,p2)) fun T_SET (p1,p2) = Token.TOKEN (ParserData.LrTable.T 29,( ParserData.MlyValue.VOID,p1,p2)) fun T_RESET (p1,p2) = Token.TOKEN (ParserData.LrTable.T 30,( ParserData.MlyValue.VOID,p1,p2)) fun T_DEBUG (p1,p2) = Token.TOKEN (ParserData.LrTable.T 31,( ParserData.MlyValue.VOID,p1,p2)) fun T_CHECK (p1,p2) = Token.TOKEN (ParserData.LrTable.T 32,( ParserData.MlyValue.VOID,p1,p2)) fun T_WITH (p1,p2) = Token.TOKEN (ParserData.LrTable.T 33,( ParserData.MlyValue.VOID,p1,p2)) fun T_ALL (p1,p2) = Token.TOKEN (ParserData.LrTable.T 34,( ParserData.MlyValue.VOID,p1,p2)) fun T_IN (p1,p2) = Token.TOKEN (ParserData.LrTable.T 35,( ParserData.MlyValue.VOID,p1,p2)) fun T_NS (p1,p2) = Token.TOKEN (ParserData.LrTable.T 36,( ParserData.MlyValue.VOID,p1,p2)) fun T_CASE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 37,( ParserData.MlyValue.VOID,p1,p2)) fun T_OF (p1,p2) = Token.TOKEN (ParserData.LrTable.T 38,( ParserData.MlyValue.VOID,p1,p2)) fun T_FOR (p1,p2) = Token.TOKEN (ParserData.LrTable.T 39,( ParserData.MlyValue.VOID,p1,p2)) fun T_OBSERVE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 40,( ParserData.MlyValue.VOID,p1,p2)) fun T_INSTALL (p1,p2) = Token.TOKEN (ParserData.LrTable.T 41,( ParserData.MlyValue.VOID,p1,p2)) fun T_SOME (p1,p2) = Token.TOKEN (ParserData.LrTable.T 42,( ParserData.MlyValue.VOID,p1,p2)) fun T_OPEN (p1,p2) = Token.TOKEN (ParserData.LrTable.T 43,( ParserData.MlyValue.VOID,p1,p2)) fun T_END (p1,p2) = Token.TOKEN (ParserData.LrTable.T 44,( ParserData.MlyValue.VOID,p1,p2)) fun T_PACK (p1,p2) = Token.TOKEN (ParserData.LrTable.T 45,( ParserData.MlyValue.VOID,p1,p2)) end end signature FILEUTILS = sig val open_fmeet_file: string -> (instream * string) end functor Main( structure Globals: GLOBALS structure Typ: TYP structure Trm: TRM structure FileUtils: FILEUTILS structure Parse: PARSE structure Leq: LEQ structure Synth: SYNTH sharing Typ.Globals = Globals and Parse.ParseRes.Typ = Typ and Parse.ParseRes.Trm = Trm and Leq.Typ = Typ and Trm.Typ = Typ and Synth.Trm = Trm and Synth.Leq = Leq val buildtime : string ) = struct open Globals; open Parse.ParseRes; val global_tenv = ref(Typ.empty_tenv) exception NotABoolean fun string_to_bool "true" = true | string_to_bool "True" = true | string_to_bool "TRUE" = true | string_to_bool "t" = true | string_to_bool "T" = true | string_to_bool "yes" = true | string_to_bool "Yes" = true | string_to_bool "YES" = true | string_to_bool "false" = false | string_to_bool "False" = false | string_to_bool "FALSE" = false | string_to_bool "f" = false | string_to_bool "F" = false | string_to_bool "no" = false | string_to_bool "No" = false | string_to_bool "NO" = false | string_to_bool _ = raise NotABoolean fun rep_loop done parser error = while (not (done())) do (case parser() of Use(f) => rep_loop_on_file f | Type_Assumption(i,pt) => let val t = Typ.debruijnify (!global_tenv) pt in write (Id.tostr i); write " <= "; Typ.prt (stdpp()) (!global_tenv) t; write "\n"; global_tenv := Typ.push_bound (!global_tenv) i t end | Type_Abbrev(i,pt) => let val t = Typ.debruijnify (!global_tenv) pt val _ = global_tenv := Typ.push_abbrev (!global_tenv) i t in write (Id.tostr i); write " == "; Typ.prt (stdpp()) (!global_tenv) t; write "\n" end | Term_Def(i,ptrm) => let val trm = Trm.debruijnify (!global_tenv) ptrm val typ = Synth.synth (!global_tenv) trm in write (Id.tostr i); write " = "; Pp.setb (stdpp()); Trm.prt (stdpp()) (!global_tenv) trm; Pp.break (stdpp()) true ~3; write " : "; Typ.prt (stdpp()) (!global_tenv) typ; Pp.break (stdpp()) true ~3; (* write " in "; Typ.prt_tenv (stdpp()) (Typ.pop (!global_tenv)); *) Pp.endb (stdpp()); write "\n"; global_tenv := Typ.push_binding (!global_tenv) i typ end | Leq(pt1,pt2) => let val t1 = Typ.debruijnify (!global_tenv) pt1 val t2 = Typ.debruijnify (!global_tenv) pt2 in if Leq.leq (!global_tenv) t1 t2 then write "Yes\n" else write "No\n" end | Nothing => () | Set(name,v) => (set_flag name (string_to_bool v)) | _ => write "Unimplemented ParseResult!\n" ) handle Typ.WrongKindOfId(te,i,which) => (write ("Wrong kind of identifier: "^ (makestring i) ^" (" ^ which ^ " expected)\nin "); Typ.prt_tenv (stdpp()) te; error()) | unknown => (write ("Exception: "^(System.exn_name unknown)^"\n"); error()) and rep_loop_on_file fname = let val (dev,real_name) = FileUtils.open_fmeet_file fname val quit = ref false fun parser() = Parse.stream_parse dev fun done() = (!quit) orelse (end_of_stream dev) fun error() = (quit := true); in write ("Reading from \"" ^ real_name ^ "\"...\n\n"); (rep_loop done parser error; write ("\nClosing " ^ real_name ^ "\n"); close_in dev) handle Io(s) => write ("IO error on " ^ fname ^ ": " ^ s ^ "\n") end fun top() = let fun top_done () = (print "> "; flush_out std_out; end_of_stream(std_in)) fun top_error () = () in write ("Welcome to FMEET (" ^ buildtime ^ ")...\n\n"); rep_loop top_done Parse.top_parse top_error; write "\n" end val read_from_file = ref ""; fun parse_switches ("-i"::s::rest) = (read_from_file := s; parse_switches rest) | parse_switches (s::rest) = (read_from_file := s; parse_switches rest) | parse_switches ([]) = () fun rep_command_line(argv,env) = (parse_switches (tl argv); if (!read_from_file) = "" then top() else rep_loop_on_file (!read_from_file) ) fun process_file s = rep_command_line (["",s^".fm"],nil); end functor WrMgt( structure Wr: WR structure Pp: PP sharing Pp.Wr = Wr ) : WRMGT = struct structure Wr = Wr; structure Pp = Pp; val current_underlying_wr = ref(Wr.to_stdout()); val current_pp = ref(Pp.pp_from_wr (!current_underlying_wr)); val current_wr = ref(Pp.wr_from_pp (!current_pp)); fun stdpp() = !current_pp; fun get_current_wr() = !current_wr; fun set_current_wr wr = (current_underlying_wr := wr; current_pp := Pp.pp_from_wr (!current_underlying_wr); current_wr := Pp.wr_from_pp (!current_pp)) fun write s = Pp.pwrite (!current_pp) s; end functor Id (structure SymTab: HASH structure InvSymTab: TABLE sharing type SymTab.elem = string and type InvSymTab.key = int ) : ID = struct val symtab = ref SymTab.empty; val invsymtab = ref (InvSymTab.empty: string InvSymTab.table); val DEBUG = ref false; type T = int exception CantHappen fun intern (s:string) = let val _ = if not (SymTab.exists(s,!symtab)) then symtab := SymTab.add(s, (!symtab)) else () val i_opt = SymTab.find (s, (!symtab)) in case i_opt of NONE => raise CantHappen | SOME(i) => (invsymtab := InvSymTab.insert((i,s), (!invsymtab)); i) end fun hashcode i = i exception UnknownId fun tostr (i:T) : string = let val s_opt = InvSymTab.find (i, (!invsymtab)) in case s_opt of NONE => raise UnknownId | SOME(s) => s end val newvarcount = ref 0; fun reset_new_counter() = (newvarcount := 0) fun new_from i = let val _ = newvarcount := !newvarcount + 1 val name = (tostr i) ^ "_" ^ (makestring (!newvarcount)) in if SymTab.exists(name,!symtab) then new_from i else intern name end val id_x = intern "x" fun new() = new_from id_x fun == (i:T) (i':T) = (i = i') fun lexlt (i:T) (i':T) = ((tostr i) < (tostr i')) end functor FileUtils(): FILEUTILS = struct fun open_fmeet_file fname = (open_in fname,fname) handle Io(s) => (open_in (fname ^ ".fm"), fname ^ ".fm") handle Io(s) => (open_in ("examples/" ^ fname), "examples/" ^ fname) handle Io(s) => (open_in ("examples/" ^ fname ^ ".fm"), "examples/" ^ fname ^ ".fm") handle Io(s) => raise Io(fname ^ " not found") end functor ParseRes (structure Typ: TYP structure Trm: TRM structure Globals: GLOBALS sharing Typ.Globals = Globals and Trm.Typ = Typ ) : PARSERES = struct structure Typ = Typ structure Trm = Trm structure Globals = Globals datatype T = Leq of Typ.pretyp * Typ.pretyp | Type_Assumption of Globals.Id.T * Typ.pretyp | Type_Abbrev of Globals.Id.T * Typ.pretyp | Term_Def of Globals.Id.T * Trm.pretrm | Term_Assumption of Globals.Id.T * Typ.pretyp | Use of string | Set of string * string | Nothing end (* ----------------------------------------------------------------------- *) (* *) (* Low-level prettyprinting stream package. Based on notes by Greg Nelson *) (* *) (* ----------------------------------------------------------------------- *) functor Pp (structure Wr: WR) : PP = struct structure Wr = Wr (* ----------------------------------------------------------------------- *) (* Utilities *) (* ----------------------------------------------------------------------- *) val DEBUG = ref false; fun debug ss = if (!DEBUG) then print ((implode ss) ^ "\n") else () fun mapunit f = let fun m ([]) = () | m (hd::tl) = ((f hd); m tl) in m end (* ----------------------------------------------------------------------- *) (* Data Structures *) (* ----------------------------------------------------------------------- *) datatype BreakBehavior = NLINDENT of int | EXPLICIT of string datatype Token = CHAR of int | SETB | ENDB | BREAK of {united:bool, do_what:BreakBehavior} | LONG of string datatype RefList = NIL | CONS of Token * (RefList ref) exception CalledErrorCont val error_cont : unit cont = callcc (fn k => (callcc (fn ek => throw k ek); raise CalledErrorCont)) exception CoroutineBug exception PPQueueOverflowed type Pp = {wr:Wr.Wr, q: Token array, qr: int ref, inp: int ref, m1: int ref, m2: int ref, m3: int ref, outq: Token array, outp: int ref, indent: int ref, margin: int ref, empty: unit cont ref, nonempty: unit cont ref} val qlen = 500; val outqlen = 500; val default_margin = 76; fun init_pp (wr:Wr.Wr) : Pp = {wr = wr, q = array(qlen, CHAR(33)), qr = ref 0, inp = ref 0, m1 = ref 0, m2 = ref 0, m3 = ref 0, outq = array(outqlen, CHAR(33)), outp = ref 0, indent = ref 0, margin = ref default_margin, empty = ref(error_cont), nonempty = ref(error_cont)} fun enqueue (pp:Pp) tok = let val {q=q, qr=qr, inp=inp, m1=m1, empty=empty, nonempty=nonempty, ...} = pp val curqr = !qr val _ = debug ["enqueue: "," qr=",makestring (!qr), " inp=",makestring (!inp), " m1=",makestring (!m1)] in debug ["enqueue"]; if ((curqr+1) mod qlen = (!inp)) orelse ((curqr+1) mod qlen = (!m1)) then raise PPQueueOverflowed else (); update(q, curqr, tok); qr := (curqr + 1) mod qlen; debug ["enqueue: about to switch"]; callcc (fn k => (empty := k; throw (!nonempty) ())); debug ["enqueue: returning"] end fun requeue (pp:Pp) = let val {q=q, qr=qr, inp=inp, empty=empty, nonempty=nonempty, m1=m1, ...} = pp val _ = debug ["requeue: "," qr=",makestring (!qr), " inp=",makestring (!inp), " m1=",makestring (!m1)] in inp := ((!inp) - 1) mod qlen end fun dequeue (pp:Pp) = let val {q=q, qr=qr, inp=inp, empty=empty, nonempty=nonempty, m1=m1, ...} = pp val _ = debug ["dequeue: "," qr=",makestring (!qr), " inp=",makestring (!inp), " m1=",makestring (!m1)] val _ = (* Front make sure there's something to dequeue *) callcc (fn k => (debug ["dequeue: checking for input"]; if (!inp) = (!qr) then (debug ["dequeue: blocking"]; nonempty := k; throw (!empty) ()) else ())) val _ = debug ["dequeue: unblocked"] val _ = if (!inp)<0 orelse (!inp)>qlen then print ("About to crash: "^(makestring (!inp))^"\n") else () val c = q sub (!inp) val _ = inp := ((!inp) + 1) mod qlen in debug ["dequeue: returning"]; c end (* ----------------------------------------------------------------------- *) (* Processing *) (* ----------------------------------------------------------------------- *) exception LineTooLong exception HowdThatGetInHere fun raw_printline (pp as {wr=wr, outq=outq, outp=outp, ...}:Pp) = let val i = ref 0 in while ((!i)<(!outp)) do (case outq sub (!i) of CHAR(c) => Wr.write_wr wr (chr c) | LONG(s) => Wr.write_wr wr s | _ => raise HowdThatGetInHere; i := (!i)+1) end fun write_tok (pp as {outq=outq, outp=outp, indent=indent, margin=margin, ...}:Pp) c raiseok = let in update (outq,!outp,c); if (!outp) < outqlen then outp := (!outp)+1 else (); case c of CHAR(10) => (raw_printline pp; indent := 0; outp := 0) | _ => (indent := (!indent)+1; if (!indent) > (!margin) andalso raiseok then raise LineTooLong else ()) end fun do_break pp indent (NLINDENT(n)) = let val i = ref 0 in write_tok pp (CHAR(10)) true; while ((!i)<n+indent) do (write_tok pp (CHAR(32)) true; i := (!i)+1) end | do_break pp indent (EXPLICIT(s)) = mapunit (fn s => enqueue pp (CHAR(ord s))) (explode s) fun P1 pp = let fun loop() = (debug ["P1_loop"]; case dequeue pp of (c as CHAR(_)) => (write_tok pp c true; loop()) | (c as LONG(_)) => (write_tok pp c true; loop()) | SETB => (P1 pp; loop()) | BREAK(_) => loop() | ENDB => ()) in debug ["P1"]; loop(); debug ["P1: finished"] end and P2 pp = let fun loop() = (debug ["P2_loop"]; case dequeue pp of (c as CHAR(_)) => (write_tok pp c true; loop()) | (c as LONG(_)) => (write_tok pp c true; loop()) | SETB => (P1 pp; loop()) | BREAK(_) => () | ENDB => ()) in debug ["P2"]; loop(); (* I think the input queue needs to be backed up by one now, so that P3 sees this SETB or BREAK... *) requeue pp; debug ["P2: finished"] end and P3 (pp as {inp=inp, outp=outp, indent=indent, m1=m1, m2=m2, m3=m3, ...} :Pp) = let val saved_indent = !indent fun loop() = (debug ["P3_loop"]; case dequeue pp of (c as CHAR(_)) => (write_tok pp c false; loop()) | (c as LONG(_)) => (write_tok pp c false; loop()) | SETB => (PP pp; loop()) | BREAK({united=true,do_what=do_what}) => (do_break pp saved_indent do_what; m1 := ~1; (* Not in CGN's original note *) loop()) | BREAK({united=false,do_what=do_what}) => (m1 := (!inp); m2 := (!outp); m3 := (!indent); ((P2 pp; m1 := ~1; (* This once seemed wrong *) debug ["P3: looping back"]; loop()) handle LineTooLong => (debug ["P3: line too long"]; inp := (!m1); outp := (!m2); indent := (!m3); do_break pp saved_indent do_what; m1 := ~1; loop()))) | ENDB => ()) in debug ["P3"]; loop() end and PP (pp as {inp=inp, outp=outp, indent=indent, m1=m1, m2=m2, m3=m3, ...} :Pp) = let in debug ["PP"]; m1 := (!inp); m2 := (!outp); m3 := (!indent); (P1 pp; m1 := ~1; debug ["PP finished"]) handle LineTooLong => (debug ["PP: line too long"]; inp := (!m1); outp := (!m2); indent := (!m3); m1 := ~1; P3 pp) end exception EndbWithNoMatchingSetb fun top_level pp = let in debug ["top_level"]; P3 pp; raise EndbWithNoMatchingSetb end (* ----------------------------------------------------------------------- *) (* Interaction *) (* ----------------------------------------------------------------------- *) fun setb pp = enqueue pp SETB fun endb pp = enqueue pp ENDB fun break pp b i = enqueue pp (BREAK {united=b, do_what=(NLINDENT i)}) fun expbreak pp b s = enqueue pp (BREAK {united=b, do_what=(EXPLICIT s)}) fun pwrite (pp as {wr=wr, ...} : Pp) s = (debug ["write: '", s, "'"]; mapunit (fn s => case ord(s) of 10 => break pp true 0 | i => enqueue pp (CHAR(i))) (explode s)) exception IllegalMargin fun set_margin (pp as {margin=margin, outp=outp , ...} : Pp) n = if (!outp) > n orelse n >= outqlen then raise IllegalMargin else margin := n (* ----------------------------------------------------------------------- *) (* Creation *) (* ----------------------------------------------------------------------- *) fun pp_from_wr wr = let val _ = debug ["new"]; val (pp as {empty=empty, ...}:Pp) = init_pp wr in callcc (fn k => (empty := k; top_level pp)); pp end fun wr_from_pp (pp as {wr=wr, ...} : Pp) = Wr.to_fn (fn s => pwrite pp s) (fn () => Wr.close wr) end (* Functor Pp *) functor Wr () : WR = struct datatype wr = WR of wr_spc * unit and wr_spc = TO_STDOUT | TO_FILE of string * outstream | TO_WRS of wr list | TO_STRING of string list ref | TO_FN of (string->unit) * (unit->unit) | TO_NOWHERE type Wr = wr fun new spc = WR(spc, ()) fun to_stdout () = new (TO_STDOUT) fun to_file name = let val out = open_out name in new (TO_FILE(name,out)) end fun to_wrs wrs = new (TO_WRS(wrs)) fun to_fn f cl_f = new (TO_FN(f,cl_f)) fun to_string () = new (TO_STRING(ref([]:string list))) fun to_nowhere () = new (TO_NOWHERE) exception Not_a_TOSTRING_Wr fun extract_str (WR(TO_STRING(ss),_)) = implode (rev (!ss)) | extract_str _ = raise Not_a_TOSTRING_Wr fun mapunit f = let fun m ([]) = () | m (hd::tl) = ((f hd); m tl) in m end fun close (WR(spc,gen)) = case spc of TO_STDOUT => () | TO_FILE(name,out) => close_out out | TO_WRS(wrs) => mapunit close wrs | TO_FN(_,cl_f) => cl_f() | TO_STRING(ss) => () | TO_NOWHERE => () fun write_wr (WR(spc,gen)) s = case spc of TO_STDOUT => output(std_out,s) | TO_FILE(_,out) => output(out,s) | TO_WRS(wrs) => mapunit (fn wr => write_wr wr s) wrs | TO_FN(f,_) => f s | TO_STRING(ss) => ss := (s :: (!ss)) | TO_NOWHERE => () end Status: not a bug. caused by illegal redundancy from include specs. See tests/bug406a.sml for shortened example. --------------------------------------------------------------------------- 430. Subscript in lookTycPath Submitter: Dave MacQueen Date: 8/3/91 Version: 0.70 Severity: serious Problem: Following code causes $$ lookTycPath 2: [2,0] tyconInContext: [2,0] messages in d70, indicating Subscript has been raised while interpreting a relative type address. Code: signature S2 = sig structure A : sig type t end datatype u = ITEM of A.t end; functor F(X : sig type v end ) = struct type w = X.v end; functor G(Y : S2) = struct structure B = F(struct type v = Y.u end) end; Comments: Problem is bad env passed to redefineCon (typing/functor.sml) during the application of functor F within the body of G. The env for the instantiated body of F is being used to interpret the type of datacon ITEM from the parameter Y: S2. lookTycPath aborts with a Subscript exception, which gets caught by ArrayExt.app in redoTycs. Status: fixed in 0.73 --------------------------------------------------------------------------- 431. ml_writev Submitter: Dave Tarditi Date: 7/1/91 Version: 0.69 Severity: minor Problem: The function ml_writev in cfuns.c for version 0.69 appears to have a bug; the reference to callc_v in it should have 1 added to it, since callc_v is a label that points to the tag of a closure, not the closure itself. By the way, callc_v is defined in the header file prim.h. Fix: The diff of the old version with the new version is below. 570d569 < extern int callc_v[]; 577,578c576,577 < MLState->ml_closure = PTR_CtoML(callc_v); < MLState->ml_pc = CODE_ADDR(PTR_CtoML(callc_v)); --- > MLState->ml_closure = PTR_CtoML(callc_v+1); > MLState->ml_pc = CODE_ADDR(PTR_CtoML(callc_v+1)); Status: Fixed in 0.74 (or earlier). --------------------------------------------------------------------------- 432. corrupted (shell) environment Submitter: Julian Bradfield <jcb@lfcs.edinburgh.ac.uk> Date: 7/1/91 Version: 0.66 System: Sparc Problem: NJ SML version 0.66 (running on Sparc) sometimes corrupts its environment: after compiling a piece of code, executed sub-processes get an environment with (apparently) random characters added to environment values. (The specific piece of code is too long to include here; I don't know how general the problem is.) Comment: [dbm] sent mail asking for code to reproduce the problem. This is the same as #342. [Bradfield confirms that problem is fixed in 0.75 in mail sent 12/5/91.] Status: fixed in 0.74 (JHR) --------------------------------------------------------------------------- 433. lexgen bug Submitter: Julian Bradfield <jcb@lfcs.edinburgh.ac.uk> Date: 7/1/91 Version: 0.66 Problem: In the lexgen.sml distributed with 0.66, there is a bug at line 1047; when outputting the arguments for the "action" function, there should be a test for !UsesTrailingContext . If true, should the third argument just be nil ? Status: fixed in 0.74 --------------------------------------------------------------------------- 434. interactive input Submitter: Lawrence Paulson <Larry.Paulson@computer-lab.cambridge.ac.uk> Date: 1/1/91 Version: 0.66 (and later) Problem: I think there's something strange with interactive I/O. Consider the following: fun prs s = output(std_out,s); val pause_tac = Tactic (fn state => (prs"** Press RETURN to continue: "; if input(std_in,1) = "\n" then Sequence.single state else (prs"Goodbye\n"; Sequence.null))); New Jersey ML waits for input and prints the prompt afterwards. The behavior of ML's I/O is not precisely defined, but most languages flush any awaiting output before demanding input. Really, I would like to accept single-character inputs (rather than lines ending with CR) but Standard ML seems to have no suitable primitive! Status: not really a bug, but a sensible request --------------------------------------------------------------------------- 435. patrow syntax Submitter: Matti Jokinen, moj@utu.fi Date: 28-Jul-1991 Version: 0.69 System: Sun 3 Severity: minor Problem: The compiler fails to accept the following patrow syntax: id:ty as pat Code: fun f {x:int as y} = x; Transcript: - fun f {x:int as y} = x; Error: Compiler bug: patType -- unexpected pattern Comments: The following patterns are translated correctly: {x = x:int as y} {x as y} {x:int} I think the bug is caused by a missing branch is in the patType function (lines 128-194 in src/typing/typecheck.sml). The parser appears to transform `id:ty as pat' into LAYEREDpat(CONSTAINTpat(_,ty),pat), which is not recognized by patType. Status: fixed in 0.74 --------------------------------------------------------------------------- 436. debugger type checking Submitter: Sergio Antoy, antoy@cs.pdx.edu Date: Jul 1, 1991 Version: 0.66 System: Sparc IPC, SunOS 4.1.1 Problem: the debugger reports tycon mismatch on a correct program Code: (* dec (x,l) is the string decimal representation of x over l characters, right justified. If l characters are not enough, then l "*" are returned. If l <= 0, then an exception is raised. *) exception wrong_field_size fun dec (x, l) = if l <= 0 then raise wrong_field_size else let fun dok (0, "") = "0" | dok (0, s) = s | dok (x, s) = dok (x div 10, chr(x mod 10 + ord("0")) ^ s) fun fill (s, l) = if size s > l then let fun dc 0 = "" | dc l = "*" ^ dc (l-1) in dc l end else let fun dc 0 = "" | dc l = " " ^ dc (l-1) in dc (l - size s) ^ s end in if x < 0 then fill ( "-" ^ (dok (~x, "")), l) else fill (dok (x, ""), l) end Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - emacsInit (); cd "/home/antares/pizza/users/antoy/programs/sml/random-dir/"; val it = () : unit val it = () : unit - usedbg "format.sml"; [opening /home/antares/pizza/users/antoy/programs/sml/random-dir/format.sml] [Major collection... 63% used (1343748/2106244), 1520 msec] [Increasing heap to 4104k] exception wrong_field_size val dec = fn : int * int -> string [closing /home/antares/pizza/users/antoy/programs/sml/random-dir/format.sml] val it = () : unit - run "dec(12,4)"; [opening <instream>] <instream>:1.1-1.9 Error: operator and operand don't agree (tycon mismatch) operator domain: int ref operand: int * int in expression: dec (12,4) [closing <instream>] - dec(12,4); val it = " 12" : string - Comments: Under epoch 3.2.4 The debugger works for a trivial factorial program. From apt@Princeton.EDU Tue Jul 2 10:28:41 1991 This is indeed a (minor) bug, which I'll handle in due course. The problem seems to be that the run function is hiding the user's (re-)definition of dec with the pervasive Integer.dec. There is a trivial work-around: call the user function something different. Status: fixed as of 0.88 --------------------------------------------------------------------------- 437. mlyacc syntax problem Submitter: Andrew Wright <wright@rice.edu> Date: 7/3/91 Version: 0.69 Problem: The source file "yacc.sml" of mlyacc from the 0.69 release does not compile under the 0.69 release because of a syntax error at line 350: EAPP(EVAR(valueStruct^"."^ if hasType (NONTERM lhs) then saySym(NONTERM lhs) else ntvoid), Fix: The "if then else" needs to be parenthesized. Status: fixed in 0.73 --------------------------------------------------------------------------- 438. callcc typing unsound Submitter: Robert Harper <rwh@proof.ergo.cs.cmu.edu> Date: 7/3/91 Version: 0.70 Severity: critical Problem: Recently Mark Lillibridge and I have been trying to investigate a number of questions of type soundness in the presence of polymorphism and control operators. As you may recall, I have been unable to find a cps transform that (1) is faithful to the ML operational semantics, and (2) admits a suitable typing result to guarantee soundness in Milner's sense. We discovered that the central issue is to do with the scope of type variables. This got us to thinking, and late last night Mark came up with the following example which demonstrates that ML with callcc and polymorphism is UNSOUND. Run it in SML/NJ to see what I mean. We plan to investigate the matter further, and will keep you posted. Code: fun left (x,y) = x; fun right (x,y) = y; let val later = (callcc (fn k => ( fn x => x, fn f => throw k (f, fn f => ()) ) )) in print (left(later)"hello"); right(later)(fn x => x+2) end Fix: Making the type of callcc weakly polymorphic appears to fix the problem. Status: fixed in 0.73 (by making callcc weakly polymorphic) --------------------------------------------------------------------------- 439. lexgen Submitter: Julian Bradfield <jcb@lfcs.edinburgh.ac.uk> Date: 7/8/91 Version: 0.66 Problem: lexgen.sml distributed with NJ SML 0.66, lines 983 to 986. The variable i in the pattern clashes with i in a pattern much higher up. I *think* that all occurrences of i in these four lines should be k, say, while the i on line 987 is indeed i. (The symptom of this bug is uncaught Substring exceptions, when a state identifier gets passed as a length to accept.) Has anybody got the look-ahead facility of ML-Lex to work? Comment: Tarditi noticed that the ASU lookahead algorithm is buggy, so this feature has been removed. Status: fixed in 0.74 --------------------------------------------------------------------------- 440. missing Perv.mos Submitter: Matti Jokinen, moj@utu.fi Date: 15-Jun-1991 Version: 0.69, 0.70, possibly others System: all Severity: major Problem: File src/runtime/Perv.mos is missing. Consequently, `makeml -pervshare' fails. Command: makeml -sun3 sunos -pervshare Transcript: makeml -sun3 sunos -pervshare ./makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run ./makeml> rm -f mo ./makeml> ln -s ../mo.m68 mo ./makeml> (cd runtime; rm -f run allmo.o allmo.s) ./makeml> (cd runtime; make MACHINE=M68 'CFL=-n ' 'DEFS= -DBSD -Dsun3 -DSUNOS - DRUNTIME=\"runtime\"' linkdata) cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -DRUNTIME=\"runtime\" -o linkdata linkdata.c (cd runtime; grep -v mo/Math.mo Perv.mos > Tmp.mos) ---> grep: Perv.mos: No such file or directory ./makeml> runtime/linkdata [runtime/Tmp.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o ./makeml> (cd runtime; make MACHINE=M68 'DEFS= -DBSD -Dsun3 -DSUNOS' CPP=/lib/ cpp 'CFL=-n ' 'AS=as') cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c run.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c run_ml.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c callgc.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c gc.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c M68.dep.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c export.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c timers.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c ml_objects.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c cfuns.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c cstruct.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c signal.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c exncode.c cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -target sun3 -c malloc.c /lib/cpp -DASM -DM68 -DBSD -Dsun3 -DSUNOS M68.prim.s > prim.s as -o prim.o prim.s cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -o run run.o run_ml.o callgc.o gc.o M68.dep. o export.o timers.o ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o prim.o allmo.o Undefined _datalist *** Error code 2 make: Fatal error: Command failed for target `run' Fix: Copy the missing file from distribution 0.66. Status: fixed in 0.73 --------------------------------------------------------------------------- 441. parsing large positive integers Submitter: Olaf Burkart <burkart@zeus.informatik.rwth-aachen.de> Date: 7/16/90 Version: 0.69 System: SPARC, SunOS 4.1 Problem: I have found the following bug in sml 0.69: Can't parse large positive integers. Can't load the Edinburgh SML Library. Problem (1): 2^30 - 1 (maxint) could not be read ----------- Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 - ~1073741824; val it = ~1073741824 : int - 1073741823; uncaught exception Overflow - Comment: [dbm] Is this the same as bug 327, which is claimed to be fixed in 0.69? Status: Fixed in 0.72. This is related to bug 327 and 444 [lg]. --------------------------------------------------------------------------- 442. Runbind exception Submitter: Olaf Burkart <burkart@zeus.informatik.rwth-aachen.de> Date: 7/16/90 Version: 0.69 System: SPARC, SunOS 4.1 Problem: It seems to me that the Runbind error from BUG 262. is back again. I tried to load the Edinburgh SML Library, but after fixing problem (1) the sml interpreter aborts with "uncaught exception Runbind" in the structure definition: structure Int: INT = struct ... exception Overflow = Overflow and Div = Div ... end Status: probably fixed; can't check without source (related bug 419 is fixed) --------------------------------------------------------------------------- 443. equality attributes in datatype specs Submitter: Colin Meldrum <colin@harlqn.co.uk> Date: Wed, 17 Jul 91 Version: 0.66 Problem: In New Jersey v66, the following signature does not elaborate: signature S = sig type 'a s datatype t = A of int -> int datatype v = D of w s and w = E of t end It gives the error: std_in:16.5-24.2 Error: inconsistent equality properties However, by swapping the two datdesc clauses in the final datatype spec the signature can be made to elaborate correctly: signature S = sig type 'a s datatype t = A of int -> int datatype w = E of t and v = D of w s end Status: fixed in 0.73 --------------------------------------------------------------------------- 444. large constants and Overflow This is an supplement to the bug: 327 large constants cause overflow in compilation from Apr 23. Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: Tue Apr 23 13:50:05 MET DST 1991 Version: 0.70 System: Sun4-60 / SunOS Release 4.1.1 Problem: The function primops in (cps/cpsopt.sml line 658) transforms integer compare operation somtimes in arithmetic operations which may raise Overflow. An example is function sizeImmed (in sparc/sparc.sml). This functions raise an Overflow for constant values bigger than (maxinit-4096) Script: Script started on Tue Jul 30 12:57:30 1991 jubu@flp 1) smln70 Standard ML of New Jersey, Version 0.70, 1 July 1991 val it = () : unit - structure TT = struct = datatype A = A | B = fun sizeImmed n = if (~4096 <= n) andalso(n < 4096) = then A else B = val sizeImmed = fn n => = (sizeImmed n) handle Overflow => ( = outputc std_out (implode[ = "sizeImmed(",makestring n, = ") overflow!\n"]); = raise Overflow ) = val x = 107374182 = val z = (sizeImmed (x * 10 + 2)) = end = ; sizeImmed(1073741822) overflow! uncaught exception Overflow Status: Fixed in 0.72. This is had to do with an illegal optimization and a bug in the sparc code generator [lg]. --------------------------------------------------------------------------- 445. spurious error report Submitter: Andrew Tolmach <apt@cs.princeton.edu> Date: 7/30/91 Version: 0.70 Problem: Following produces a spurious error in 0.70. Code: signature T = sig datatype debuglevel = A of instream option end Status: fixed in 0.73 --------------------------------------------------------------------------- 446. Compiler bug Submitter: jont%uk.co.harlqn@uk.ac.ukc Date: 01/08/91 Version: SML of NJ version number 0.66 System: Sun 4/330 with SunOS 4.1.1 Severity: minor Problem: Compiler warns of compiler bug in compiling some incorrect code Code: (* _mirprint.sml the functor *) (* $Log: _mirprint.sml,v $ Revision 1.3 91/07/30 16:22:11 jont Printed more opcodes (branch and cgt) Revision 1.2 91/07/26 20:00:13 jont Redid some printing in light of changes in mirtypes Revision 1.1 91/07/25 15:45:09 jont Initial revision Copyright (c) 1991 Harlequin Ltd. *) require "../utils/integer"; require "../basics/identprint"; require "../lambda/pretty"; require "../lambda/lambdasub"; require "mirtypes"; require "mirprint"; functor MirPrint( structure Integer : INTEGER structure IdentPrint : IDENTPRINT structure MirTypes : MIRTYPES structure Pretty : PRETTY structure LambdaSub : LAMBDASUB sharing IdentPrint.Ident = MirTypes.Ident hsaring MirTypes.LambdaTypes = LambdaSub.LambdaTypes ) : MIRPRINT = struct structure MirTypes = MirTypes structure P = Pretty exception pretty_not_done_yet fun decode_binary MirTypes.ADD = "ADD " | decode_binary MirTypes.SUB = "SUB " | decode_binary MirTypes.MUL = "MUL " | decode_binary MirTypes.DIV = "DIV " | decode_binary MirTypes.REM = "REM " | decode_binary MirTypes.AND = "AND " | decode_binary MirTypes.OR = "OR " | decode_binary MirTypes.EOR = "EOR " | decode_binary MirTypes.SHL = "SHL " | decode_binary MirTypes.SHR = "SHR " | decode_binary MirTypes.SHRL = "SHRL " | decode_binary MirTypes.DIVL = "DIVL " | decode_binary MirTypes.REML = "REML " fun decode_unary MirTypes.CMP = "CMP " | decode_unary MirTypes.CMPL = "CMPL " | decode_unary MirTypes.MOV = "MOV " | decode_unary MirTypes.NEG = "NEG " | decode_unary MirTypes.NOT = "NOT " fun decode_store MirTypes.LDX = "LDX " | decode_store MirTypes.STX = "STX " fun decode_allocate MirTypes.ALLOC = "ALLOC " | decode_allocate MirTypes.ALLOC_REAL = "ALLOC_REAL " | decode_allocate MirTypes.ALLOC_STRING = "ALLOC_STRING " fun decode_branch MirTypes.BRA = "BRA " | decode_branch MirTypes.BEQ = "BEQ " | decode_branch MirTypes.BNE = "BNE " | decode_branch MirTypes.BHI = "BHI " | decode_branch MirTypes.BLS = "BLS " | decode_branch MirTypes.BHS = "BHS " | decode_branch MirTypes.BLO = "BLO " | decode_branch MirTypes.BGT = "BGT " | decode_branch MirTypes.BLE = "BLE " | decode_branch MirTypes.BGE = "BGE " | decode_branch MirTypes.BLT = "BLT " | decode_branch MirTypes.BVS = "BVS " | decode_branch MirTypes.BVC = "BVC " | decode_branch MirTypes.BMI = "BMI " | decode_branch MirTypes.BPL = "BPL " fun decode_adr MirTypes.LEA = "LEA " fun decode_real_gc(MirTypes.GC_REAL gc_reg) = "REG " ^ MirTypes.print_gc_register gc_reg | decode_real_gc(MirTypes.GC_SPILL i) = "SPILL " ^ Integer.makestring i fun decode_real_non_gc(MirTypes.NON_GC_REAL gc_reg) = "REG " ^ MirTypes.print_non_gc_register gc_reg | decode_real_non_gc(MirTypes.NON_GC_SPILL i) = "SPILL " ^ Integer.makestring i fun decode_reg_operand(MirTypes.GC_REG(gc_reg, real_gc_reg_opt)) = "GC(" ^ MirTypes.print_gc_register gc_reg ^ (case real_gc_reg_opt of MirTypes.ABSENT => "" | MirTypes.PRESENT real_gc => decode_real_gc real_gc) ^ ") " | decode_reg_operand(MirTypes.NON_GC_REG(non_gc_reg, real_non_gc_reg_opt)) = "NON_GC(" ^ MirTypes.print_non_gc_register non_gc_reg ^ (case real_non_gc_reg_opt of MirTypes.ABSENT => "" | MirTypes.PRESENT real_non_gc => decode_real_non_gc real_non_gc) ^ ") " fun decode_gp_op(MirTypes.GP_GC_REG(gc_reg, real_gc_reg_opt)) = "GC(" ^ MirTypes.print_gc_register gc_reg ^ (case real_gc_reg_opt of MirTypes.ABSENT => "" | MirTypes.PRESENT real_gc => decode_real_gc real_gc) ^ ") " | decode_gp_op(MirTypes.GP_NON_GC_REG(non_gc_reg, real_non_gc_reg_opt)) = "NON_GC(" ^ MirTypes.print_non_gc_register non_gc_reg ^ (case real_non_gc_reg_opt of MirTypes.ABSENT => "" | MirTypes.PRESENT real_non_gc => decode_real_non_gc real_non_gc) ^ ") " | decode_gp_op(MirTypes.GP_IMM_INT imm) = "Int(" ^ Integer.makestring imm ^ ") " | decode_gp_op(MirTypes.GP_IMM_ANY imm) = "Any(" ^ Integer.makestring imm ^ ") " fun decode_op(MirTypes.BINARY(binary_op, reg_op, gp_op1, gp_op2)) = decode_binary binary_op ^ decode_reg_operand reg_op ^ decode_gp_op gp_op1 ^ decode_gp_op gp_op2 | decode_op(MirTypes.UNARY(unary_op, reg_op, gp_op)) = decode_unary unary_op ^ decode_reg_operand reg_op ^ decode_gp_op gp_op | decode_op(MirTypes.STOREOP(store_op, reg_op1, reg_op2, gp_op)) = decode_store store_op ^ decode_reg_operand reg_op1 ^ decode_reg_operand reg_op2 ^ decode_gp_op gp_op | decode_op(MirTypes.ALLOCATE(allocate, gc_reg, imm)) = decode_allocate allocate ^ "GC(" ^ MirTypes.print_gc_register gc_reg ^ ") " ^ (case allocate of MirTypes.ALLOC_REAL => "" | _ => Integer.makestring imm) | decode_op(MirTypes.BRANCH(branch, tag)) = decode_branch branch ^ MirTypes.print_tag tag | decode_op(MirTypes.SWITCH(cgt, reg_op, tag_list)) = LambdaSub.reduce_left (fn (s, tag) => s ^ " " ^ MirTypes.print_tag tag) ("CGT " ^ decode_reg_operand reg_op, tag_list) | decode_op(MirTypes.VALUE scon) = (case scon of IdentPrint.Ident.REAL _ => "Real " | IdentPrint.Ident.STRING _ => "String " | _ => raise(LambdaSub.LambdaTypes.impossible"VALUE(int)")) ^ IdentPrint.printSCon scon | decode_op(MirTypes.ADR(adr, reg_op, tag)) = decode_adr adr ^ decode_reg_operand reg_op ^ " " ^ MirTypes.print_tag tag (* Information points *) | decode_op(MirTypes.LOC_REF tag_list) = LambdaSub.reduce_left op ^ ("Local references\n", map (fn tag => MirTypes.print_tag tag ^ " ") tag_list) | decode_op MirTypes.END = "End of code" | decode_op _ = raise(pretty_not_done_yet) (* | decode_op(MirTypes.BINARYFP of binary_fp_op * fp_register * fp_register * fp_operand | | decode_op(MirTypes.UNARYFP of unary_fp_op * fp_register * fp_operand | | decode_op(MirTypes.STACKOP of stack_op * reg_operand | | decode_op(MirTypes.STOREFPOP of store_fp_op * fp_register * reg_operand * gp_operand | | decode_op(MirTypes.CONVOP of int_to_float * fp_register * reg_operand | | decode_op(MirTypes.BRANCH_AND_LINK of branch_and_link * bl_dest | | decode_op(MirTypes.INIT of any_register | (* Register is initialised here *) | decode_op(MirTypes.USE of any_register | (* Register is used here *) | decode_op(MirTypes.ENTER of int * reg_operand | (* Entry point for procedure, with n locals and arg reg *) | decode_op(MirTypes.EXIT of reg_operand | (* Return point from procedure, result in reg *) (* Data *) *) fun decode_block(MirTypes.BLOCK(tag, op_list)) = P.blk(0, P.lst("", [P.nl], "") (P.blk(2, [P.str("Tag "), P.str(MirTypes.print_tag tag)]) :: (map (fn x => P.str(" " ^ decode_op x)) op_list))) fun print_mir_code(MirTypes.CODE block_list) = P.string_of_T(P.blk(0, P.lst("", [P.nl], "") (map decode_block block_list))) end Transcript: make "../mir/_mirprint.sml"; [opening /home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml] val it = () : unit val it = () : unit val it = () : unit val it = () : unit val it = () : unit val it = () : unit /home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml:30.3-30.9 Error: syntax error: inserting OPEN /home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml:30.3-30.54 Error: unbound structure in signature: hsaring /home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml:30.3-30.54 Error: unbound structure in signature: MirTypes.LambdaTypes Error: Compiler bug: lookPathSTRinSig.get [closing /home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml] Comments: The code is incorrect, but it shouldn't cause the compiler to claim it has a bug in itself! The cause seems somewhat related to the fact that MirTypes has no substructure LambdaTypes, simply misspelling sharing on a line which is an otherwise valid sharing constraint line does not exhibit the problem. Status: possibly fixed in 0.73? (incomplete source, can't test) --------------------------------------------------------------------------- 447. identity type abbreviation Submitter: tmb@ai.mit.edu Date: 08/02/91 Version: 0.70 System: Sun4/OS4.1.1 Severity: ? Problem: the type checker refuses to accept the following definition Code: structure S = struct type 'b data = 'b list type 'b value = 'b fun at(x:'b data):'b value = hd x end; Transcript: hack.sml:5.2-5.34 Error: expression and constraint don't agree (bound type var) expression: 'bU constraint: 'bU value in expression: Initial.hd x Comments: I'm not sure whether this is a bug, but certain types of functors seem to be difficult to express if you cannot write definitions like this. In particular, it seems like I have to write two separate functors depending on whether "'b value" is simply "'b" or whether it is some other type dependent on "'b" (e.g., "'b list"). This seems very unnatural. signature S = sig type 'a data type 'a value val at: 'b data -> 'b value end; functor F(structure X:S) = struct open X fun pair_at x = (at x,at x) end; structure A = struct type 'a data = 'a list type 'a value = 'a list val at = (fn x => x) end; structure FA = F(structure X = A); structure B = struct type 'a data = 'a list type 'a value = 'a val at = hd end; (* why can't I do this??? *) structure FB = F(structure X = B); Fix: type abbreviations must be expanded when unifying with UBOUND type variables in Unify (basics/unify.sml). The definition of equalTypes in TypesUtil must be changed in a similar manner. Status: fixed in 0.74 --------------------------------------------------------------------------- 448. failure to build on MIPS 6280 Submitter: Dave MacQueen Date: 8/10/91 Version: 0.71 System: MIPS 6280, RISCOS 4.52 Severity: critical (for 6280) Problem: failure while trying to bootstap the compiler Transcript: % makeml -mips riscos -batch -m 60000 makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.mipsb mo makeml> (cd runtime; rm -f run allmo.o allmo.s) makeml> (cd runtime; make MACHINE=MIPS 'CFL= -systype bsd43' 'LIBS=' 'DEFS= -DRISCos -DRUNTIME=\"runtime\"' linkdata) cc -O -systype bsd43 -DMIPS -DRISCos -DRUNTIME=\"runtime\" -o linkdata linkdata.c makeml> runtime/linkdata [runtime/CompMipsBig.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o makeml> (cd runtime; make MACHINE=MIPS 'DEFS= -DRISCos' 'CPP=/lib/cpp -P' 'CFL= -systype bsd43' 'AS=as' 'LIBS=') cc -O -systype bsd43 -DMIPS -DRISCos -c run.c cc -O -systype bsd43 -DMIPS -DRISCos -c run_ml.c cc -O -systype bsd43 -DMIPS -DRISCos -c callgc.c cc -O -systype bsd43 -DMIPS -DRISCos -c gc.c uopt: Warning: gc: this procedure not optimized because it exceeds size threshold; to optimize this procedure, use -Olimit option with value >= 553. cc -O -systype bsd43 -DMIPS -DRISCos -c MIPS.dep.c cc -O -systype bsd43 -DMIPS -DRISCos -c export.c cc -O -systype bsd43 -DMIPS -DRISCos -c timers.c cc -O -systype bsd43 -DMIPS -DRISCos -c ml_objects.c cc -O -systype bsd43 -DMIPS -DRISCos -c cfuns.c cc -O -systype bsd43 -DMIPS -DRISCos -c cstruct.c cc -O -systype bsd43 -DMIPS -DRISCos -c signal.c cc -O -systype bsd43 -DMIPS -DRISCos -c exncode.c cc -O -systype bsd43 -DMIPS -DRISCos -c malloc.c cc -O -systype bsd43 -DMIPS -DRISCos -c mp.c cc -O -systype bsd43 -DMIPS -DRISCos -c sync.c /lib/cpp -P -DASM -DMIPS -DRISCos MIPS.prim.s > prim.s as -o prim.o prim.s as0: Warning: prim.s, line 281: missing .end preceding this .ent: set_request .ent set_request as0: Warning: prim.s, line 281: .ent/.end block never defined the procedure name as0: Warning: prim.s, line 407: missing .end preceding this .ent: go .ent go cc -O -systype bsd43 -DMIPS -DRISCos -o run run.o run_ml.o callgc.o gc.o MIPS.dep.o export.o timers.o ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o mp.o sync.o prim.o allmo.o makeml> runtime/run -m 60000 -r 5 -h 2048 CompMipsBig [Increasing heap to 2048k] [Loading mo/CoreFunc.mo] [Executing mo/CoreFunc.mo] [Loading mo/Math.mo] [Executing mo/Math.mo] [Loading mo/Initial.mo] [Executing mo/Initial.mo] Uncaught exception CFunNotFound with "argv" 9.2u 7.8s 1:22 20% 182+737k 1269+1532io 2586pf+0w Comments: The as0 warnings should be eliminated, and the -Olimit flag added or changed so that the gc code can be optimized. Status: Fixed in 0.78 --------------------------------------------------------------------------- 449. poor error message for mismatching datatype spec Submitter: John Reppy (jhr@cs.cornell.edu) Date: Mar 5 1991 Version: 0.66-0.69 Severity: minor Problem: Here is another example of an error message that doesn't give enough info: user/drawing.sml:9.3-12.5 Error: mismatching datatype spec: pen_val_t In this case, pen_val_t has ~30 variants; figuring out the mismatch is a pain. This is like the problem with large labeled records. - John Status: fixed in 0.91 (dbm) --------------------------------------------------------------------------- 450. Compiler bug: tycPath Submitter: Andy Koenig (dopey!ark) Date: 10/16/91 Version: 0.66 Severity: minor Problem: After an unmatched type spec there is a Compiler bug message. Transcript: - signature I = sig type T end; signature I = sig type T end - abstraction J : I = struct type u = int end; std_in:1.21-1.43 Error: unmatched type spec: T Error: Compiler bug: tycPath Status: fixed in 0.74 --------------------------------------------------------------------------- 451. sharing constraints Submitter: Mike Crawley <mjc@abstract-hardware-ltd.co.uk> Date: 10/29/91 Version: 0.73 Severity: serious Problem: SML/NJ 0.73 gets the sharing constraints wrong in the following ML. Code: signature A = sig structure Base:sig end end; signature P = sig end; functor A (structure P:P) : A = struct structure Base = P; end; signature B = sig structure Base:sig end end; functor B (structure P:P structure A:A sharing P = A.Base ) : B = struct structure Base = P; end; functor Q(structure P : P structure A : A structure B : B sharing P = A.Base = B.Base) = struct end ; structure P = struct end ; structure A = A(structure P = P); structure B = B(structure P = P structure A = A); structure Q = Q(structure P = P structure A = A structure B = B); Status: fixed in 0.75 --------------------------------------------------------------------------- 452. finding out what is in a structure Submitter: Tim Freeman, tsf@cs.cmu.edu Date: Wed Oct 30 15:30:02 1991 Version: 0.74 System: Sun 4 Severity: minor but chronic Problem: I used to be able to find out what was in a structure by opening it up. Now there is apparently no way to remind myself of what is in a structure other than by reading the source. Transcript: - structure x = SourceGroup; structure x : SOURCEGROUP (* This used to tell me all of the things in the SourceGroup structure. *) - open x; open x (* I would be just as happy if this printed out the information I want too. *) Comments: Maybe this feature should have its own name, instead of hanging off of top level structure declarations. --------------------------------------------------------------------------- 453. unhandled exception crashes sml Submitter: Tim Freeman <tsf@cs.cmu.edu> Date: Thu Oct 31 15:32:46 1991 Version: 0.74 System: Sun 4 running some version of Mach Severity: minor Problem: With some manipulations of structures, raising unhandled exceptions causes SML to bomb. Code: bug3.sml contains: structure Util = struct exception Bug of string end structure InstProto = struct structure U = Util structure S = struct end end open InstProto ; raise U.Bug "hi" Transcript: % sml Standard ML of New Jersey, Version 0.74, 10 October, 1991 Prerelease version. Arrays have changed; see doc/NEWS val it = () : unit - use "bug3.sml"; [opening bug3.sml] structure Util : sig exception Bug of string end structure InstProto : sig structure S : ... structure U : ... end open InstProto SIGILL code 0x7 % Comments: Earlier during the process of narrowing down this bug, it was saying uncaught exception random binary garbage (except you have to imagine the string "random binary garbage" replaced by random binary garbage) instead of getting the SIGILL trap. Status: fixed in 0.75 --------------------------------------------------------------------------- 454. running out of memory Submitter: Andy Koenig Date: 11/7/91 Version: 0.74 System: SPARCstation, 64MB Severity: minor Problem: SML-NJ is not very nice about handling memory exhaustion. Transcript: [boojum] sml Standard ML of New Jersey, Version 0.74, 10 October, 1991 Prerelease version. Arrays have changed; see doc/NEWS val it = () : unit - fun f x = f(0::x); val f = fn : int list -> 'a - f nil; [Increasing heap to 3164k] [Increasing heap to 4452k] [Increasing heap to 5456k] [Major collection... [Increasing heap to 8192k] 76% used (3427160/4508104), 2610 msec] [Increasing heap to 13192k] [Major collection... 49% used (4497848/8999168), 4600 msec] [Increasing heap to 26380k] [Major collection... 49% used (8999168/18002072), 9250 msec] [Increasing heap to 27204k] [Major collection... [Increasing heap to 27620k] [Increasing heap to 27776k] [Increasing heap to 27860k] [Increasing heap to 27880k] Warning: can't increase heap Ran out of memory[boojum] Comments: While I do ultimately expect some kind of drastic termination, I do **NOT** expect to be unceremoniously dumped out of ML back into the Shell. A more reasonable strategy might be to preallocate a chunk of memory to be used as secondary storage while recovering from exhaustion of primary storage. That, at least, would allow for a return to top level and associated garbage collection, which, in many cases, would allow interactive execution to resume. Incidentally, this example was run on a Sparcstation with 64 megabytes of physical memory and no limit on process size that I know of. I don't know why it gave up the ghost at 28 megabytes -- do you? Status: open --------------------------------------------------------------------------- 455. handling Real.Div Submitter: olender@cs.colostate.edu <Kurt Olender> Date: Nov. 11, 1991 Version: 0.75 System: Sparcstation-2/SunOS 4.1.1 Severity: minor Problem: cannot handle Real.Div exception Code: 1.0/0.0 handle Real.Div => 10.0; Transcript: (* At top level *) (* Integer works *) - 1 div 0 handle Integer.Div => 10; val it = 10 : int (* Real doesn't *) - 1.0/0.0 handle Real.Div => 10.0; uncaught exception Div (* Even when I don't specify the name *) - 1.0/0.0 handle _ => 10.0; uncaught exception Div Fix: This was a bug in the scheduler dependencies for the SPARC. Status: fixed in 0.76 --------------------------------------------------------------------------- 456. signals on SPARC cause heap corruption Submitter: tyan@cs.cornell.edu & Greg_Morrisett@CS.CMU.EDU Date: Nov. 20, 1991 Version: 0.75 (and earlier) System: Sparc Severity: minor Problem: programs using signals to do pre-emption get corrupted heaps. Code: (* A simple preemptive thread structure *) structure T = struct (* Queues *) type '1a queue = ('1a list ref * '1a list ref) fun create () = (ref [], ref []) fun enq ((f,r), x) = r := x :: (!r) fun deq (f,r) = (case (!f) of (hd::tl) => (f := tl; SOME hd) | [] => (case (rev (!r)) of (hd::tl) => (f := tl; r := []; SOME hd) | [] => NONE)) (* Flag for atomicity *) val atomic = ref false (* Ready queue *) val ready : unit cont queue = create () exception Deadlock fun enterAtomic () = atomic := true fun leaveAtomic () = atomic := false fun reschedule k = enq (ready, k) fun get_next () = case (deq ready) of NONE => raise Deadlock | SOME k => k (* fork a thread *) fun fork f = (enterAtomic (); callcc (fn c => (reschedule c; leaveAtomic (); f (); enterAtomic (); throw (get_next ()) ())); leaveAtomic ()) fun prepend f kont = (callcc (fn c => (callcc (fn k => (throw c k)); f (); throw kont ()))) (* context switch signal handler *) fun handler (n,kont) = if (!atomic) then (kont) else (enterAtomic (); reschedule (prepend leaveAtomic kont); get_next ()) local open System.Signals System.Timer System.Unsafe.CInterface val t0 = TIME {sec=0,usec=0} in val _ = setHandler (SIGALRM, SOME handler) fun setPreempt NONE = setitimer(0,t0,t0) | setPreempt (SOME t) = let val t = TIME {sec=0,usec=1000*t} in setitimer(0,t,t) end end end fun spin_alloc l = spin_alloc (rev l); (* make sure we fool compiler *) fun spin () = spin_alloc [1,2]; fun bug () = (T.setPreempt (SOME 50); T.fork spin; T.fork spin; T.fork spin) Fix: The problem was that the SPARC has no callee saved FP registers, so the resumption continuation was pointing to its own descriptor. Status: fixed in 0.76 --------------------------------------------------------------------------- 457. Real.ceiling has wrong type Submitter: Lal George Date: Nov. 22, 1991 Version: 0.75 (and earlier) System: all Severity: minor Problem: Real.ceiling has wrong type Code: - ceiling; val it = fn : real -> 'a Remark: yet another example of the brain damage in perv.sml Status: fixed in 0.76 --------------------------------------------------------------------------- 458. incorrect 'Warning: binding not exhaustive' message Submitter: Lal George Date: Nov. 27, 1991 Version: 0.75 (and earlier) System: all Severity: minor Code: datatype register = Reg of int | Freg of int datatype ea = Direct of register | Immed of int val dataptr as Direct dataptr' = Direct(Reg 23) Transcript: - val dataptr as Direct dataptr' = Direct(Reg 23); std_in:4.1-4.47 Warning: binding not exhaustive dataptr as Direct dataptr' = ... val dataptr = Direct (Reg 23) : ea val dataptr' = Reg 23 : register Comment: [dbm] Further static analysis could verify that this pattern would be matched, but this analysis is not done. Status: not a bug --------------------------------------------------------------------------- 459. signature matching Submitter: Robert Thau, rst@ai.mit.edu Date: 10 December 1991 Version: 75 System: Sparcstation 1 / SunOS 4.1.1 Severity: Problem: The following two lines of admittedly questionable code seem to throw the SML/NJ compiler into a loop, madly consing with no apparent end in sight. Code: signature foosig = sig val foo: 'a -> int end; structure foostruct:foosig = struct fun foo x = x end; Status: fixed in 0.80 (or earlier) --------------------------------------------------------------------------- 460. signature matching Submitter: Tsung-Min Kuo (email : kuo@ecrc.de) Date: Dec 12, 1991 Version: Version 0.75, November 11, 1991 System: SPARCstation 1, SUNOS 4.1 Severity: VERY severe Problem: Compiler blowup --- use up 24M heap Code: signature A = sig val s : (unit -> 'a) -> unit end structure A : A = struct fun s f = f() end Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - signature A = sig val s : (unit -> 'a) -> unit end; signature A = sig val s : (unit -> 'a) -> unit end - structure A : A = struct fun s f = f() end; [Increasing heap to 10003k] [Major collection... 69% used (3607244/5171504), 6790 msec] [Increasing heap to 15147k] [Major collection... [Increasing heap to 23187k] 80% used (7597900/9458020), 12920 msec] [Increasing heap to 23467k] [Major collection... 73% used (9457996/12885048), 17240 msec] [Increasing heap to 23575k] 2[Major collection... [Increasing heap to 23647k] Warning: can't increase heap Ran out of memory Comments: The signature was wrong. But, instead of reporting spec mismatch, it keeps on doing heap allocation until runs out of memory. By fixing the signature, or by avoiding signature constraint on the structure definition, we can get around the bug. The old version (0.66) seems working correctly on this example. Submitter: Francois Bourdoncle <bourdoncle@prl.dec.com> Date: 3/13/92 Version: 0.75 System: Ultrix 4.2 on a DECstation 5200 (but also VAX 8600) Problem: compiler loops on erroneous signature matching Code: signature SIG = sig val F : 'a -> unit end structure S : SIG = struct fun F x = x end; Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "bug.sml"; [opening bug.sml] [Increasing heap to 4058k] [Increasing heap to 7678k] [Increasing heap to 14398k] [Increasing heap to 16386k] [Major collection... 69% used (5815684/8396812), 7367 msec] [Increasing heap to 24602k] ^C[closing bug.sml] Interrupt - ^C Status: fixed in 0.80 (or earlier) --------------------------------------------------------------------------- 461. overloading and weak polymorphism Submitter: jont@uk.co.harlqn Date: Version: SML of NJ version number, 0.75 System: Sun 4/330 with SunOS 4.1.1 Severity: minor Problem: Problem with weak type variables Code: local val x = ref nil in fun define(y: string list) = x := y end; Transcript: - use "bug461.sml"; bug461.sml:5.3-5.17 Error: nongeneric weak type variable x : '0Z list ref [closing bug461.sml] Comments: 0.66 accepted this quite happily. As far as I can see, there is no problem deducing the type of overloads Status: fixed in 0.89 --------------------------------------------------------------------------- 462. location info in inexhaustive pattern warnings Submitter: Bob Harper (Robert_Harper@cs.cmu.edu) Date: 12/4/91 Version: 0.75 Problem: My inexhaustive pattern warnings come out thus these days: .../src/type-check.sml:0.0-0.0 Warning: match not exhaustive The line and column number are not 0! The messages always have 0 for both. Comment: Is marking turned off? Status: fixed in 0.89 --------------------------------------------------------------------------- 463. unmatched datatype in signature matching Submitter : Sylvie Thiebaux sylvie@gmd.de Date 10 - 07 - 91 Version SML 0.66 Severity major (critical ?) Problem : unmatched datatype Code : I cannot narrow down the cause of the problem more than I have already done. I have got several files in which I let only the necessary things. All the files excpeted the main file can be compliled. When I compile the main file I get the error ``unmatched datatype literal'' at the point indicated in the program. It is maybe a problem of a sharing constraint on this type that I have given in the file LOGIC.sml. But I have already used the LOGIC signature in a larger programm and this sharing constraint seemed to cause no problem. Here are all the modules involved in the error message. Please do not be surprised about what each module contains. I need each of them but I wanted to let in each of them only the minimal necessary code in order to make your task easier. (*file ELEMENT.sml*) signature ELEMENT = sig type element val put : outstream -> element -> unit end (************************************************************) (*file EQ.sml*) import "ELEMENT"; signature EQ = sig include ELEMENT val eq : element -> element -> bool end (**********************************************************) (*file SET.sml*) import "EQ"; signature SET = sig structure Eq : EQ type element sharing type element = Eq.element type set; val empty_set : set (* unrelated to the error *) end (**********************************************************) (*file ListSet.sml*) import "EQ"; import "SET"; functor ListSet (Eq' :EQ) : SET = struct structure Eq = Eq' type element = Eq.element type set = element list val empty_set :set = [] end (********************************************************) (* file ATOMS.sml *) signature ATOMS = sig type term type atom val eq_at : atom -> atom -> bool val put_at : outstream -> atom -> unit end (******************************************************) (*file LOGIC.sml*) import "SET"; import "ATOMS"; signature LOGIC = sig structure At : ATOMS datatype literal = False | True | neg of At.atom | pos of At.atom type conj_set structure CS : SET sharing type literal = CS.element (* if you remove this sharing constraint, the error does not exist any more. But I need this constraint and anyway, it caused no problem whith other big programms including this signature *) and type conj_set = CS.set end (************************************************************************) (*file Logic.sml*) import "ListSet"; import "ATOMS"; import "LOGIC"; functor Logic ( atoms : ATOMS ) : LOGIC = struct structure At = atoms datatype literal = pos of At.atom | neg of At.atom | True | False fun put_lit os (pos at) = At.put_at os at | put_lit os (neg at) = ((output (os,"-")); (At.put_at os at)) | put_lit os (True) = output(os,"true") | put_lit os (False) = output(os,"false") fun eq_lit (pos at1 :literal) (pos at2 :literal) = At.eq_at at1 at2 | eq_lit (neg at1 :literal) (neg at2 :literal) = At.eq_at at1 at2 | eq_lit True True = true | eq_lit False False = true | eq_lit _ _ = false structure CS = ListSet (struct type element = literal val eq = eq_lit val put = put_lit end) type conj_set = CS.set end (*****************************************************************) (*file LOGIC_JUSTIF.sml*) import "LOGIC"; signature LOGIC_JUSTIF = sig structure L : LOGIC datatype rule = implication of L.literal list * L.literal | inconsistency of L.literal list end (***************************************************************) (* file Logic_justif.sml*) import "ATOMS"; import "Logic"; import "LOGIC_JUSTIF"; functor Logic_justif (atoms: ATOMS) : LOGIC_JUSTIF = struct structure L : LOGIC = Logic(atoms) datatype rule = implication of L.literal list * L.literal | inconsistency of L.literal list end (****************************************************************) (*file LOGIC_JUSTIF_AND_INIT.sml *) import "LOGIC_JUSTIF"; signature LOGIC_JUSTIF_AND_INIT = sig structure LJ : LOGIC_JUSTIF val background_knowledge : LJ.rule list end (****************************************************************) (* file POSS.sml *) import "LOGIC"; signature POSS = sig structure L : LOGIC end (***************************************************) (*file Poss.sml *) import "LOGIC_JUSTIF_AND_INIT"; import "POSS"; functor Poss (lji : LOGIC_JUSTIF_AND_INIT) : POSS = struct structure L = lji.LJ.L end (***************************************************) (*file NOTHING.sml*) import "POSS"; signature NOTHING = sig structure P : POSS end (***********************************) (* file Nothing.sml*) import "POSS"; import "NOTHING"; functor Nothing (PW:POSS) : NOTHING = struct structure P = PW end (***********************************) (* main programm : Block.sml*) import "Logic_justif"; import "Poss"; import "NOTHING"; (* curiously, if you remove this last import, the error message does not appear *) structure atoms = struct datatype term = a | b | c datatype atom = on of term * term | ontable of term | holding of term | clear of term | handempty fun t2s a = "a" | t2s b = "b" | t2s c = "c" fun a2s (on(X,Y)) = "on("^(t2s X)^", "^(t2s Y)^")" | a2s (ontable X) = "ontable("^(t2s X)^")" | a2s (holding X) = "holding("^(t2s X)^")" | a2s (clear X) = "clear("^(t2s X)^")" | a2s handempty = "handempty" fun put_at os (at:atom) = output(os, a2s(at)) fun eq_at (at1:atom) (at2:atom) = at1=at2 end structure logic_justif : LOGIC_JUSTIF = Logic_justif(atoms) open logic_justif open L open atoms val back_klg = nil structure logic_justif_and_init : LOGIC_JUSTIF_AND_INIT = struct structure LJ = logic_justif val background_knowledge = back_klg end (******************************************) structure poss : POSS = Poss(logic_justif_and_init) (* this is the line where the error message appears *) Comment: may be fixed in 0.75 -- check. Status: fixed in 0.88 --------------------------------------------------------------------------- 464. defining exception as data constructor Submitter: David Tarditi Date: 7/19/91 Version: 0.70 Severity: minor Problem: The following results in a compiler bug message in version 0.70: datatype d = D; exception e = D; The error message is: Error: Compiler bug: in makedec EXCEPTIONdec Comment: This is probably due to the fact that exceptions and constructors share the same name space. A check that the binding for the rhs of "exception e = ..." is an exception is probably missing. Status: fixed in 0.75 --------------------------------------------------------------------------- 465. opening unbound structure id in signature Submitter: David Tarditi Date: 7/19/91 Version: 0.70 Severity: minor Problem: The compiler falls over with the exception UnboundTable if you try to open an undefined structure in a signature. Code: signature S = sig open T (* T is undefined *) end Status: fixed in 0.75 --------------------------------------------------------------------------- 466. looping error message Submitter: Matti Jokinen, moj@utu.fi Date: 22-Jun-1991 Version: 0.69, 0.70, possibly others System: probably all Severity: minor for an experienced user, but confusing to novices Problem: unterminating error message Code: fun f (p,q) = let fun g (p,q) = #1 q orelse f (p,q) in g (p, #2 q) end; Transcript: - fun f (p,q) = = let fun g (p,q) = #1 q orelse f (p,q) = in g (p, #2 q) = end; std_in:2.9-2.41 Error: unresolved flex record in let pattern type: {1:bool,...} std_in:1.1-4.3 Error: unresolved flex record in let pattern type: {1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1 :bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1 :bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1 :bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1 - - - Comments: Can be interrupted with ^c. Status: fixed in 0.80 --------------------------------------------------------------------------- 467. missing newline in declaration echo Submitter: Matti Jokinen (moj@utu.fi) Date: 23-Jul-1991 Version: 0.69, 0.70, possibly others System: all Severity: minor Problem: Fixity declarations are echoed without newlines. Code: infix L; infixr R; nonfix N; Transcript: - infix L; infixr R; nonfix N; infix Linfixr Rnonfix N- ^ This is the next prompt. Fix: Add `newline()' at the end of the printFixity function defined in src/print/printdec.sml: *** printdec.sml.orig Thu Mar 14 17:50:22 1991 --- printdec.sml Mon Jul 22 04:11:27 1991 *************** *** 215,227 **** and printFixity{fixity,ops} = (case fixity of NONfix => print "nonfix " | INfix (i,_) => (if i mod 2 = 0 then print "infix " else print "infixr "; if i div 2 > 0 then (print (i div 2); print " ") else ()); ! printSequence " " printSym ops) --- 215,228 ---- and printFixity{fixity,ops} = (case fixity of NONfix => print "nonfix " | INfix (i,_) => (if i mod 2 = 0 then print "infix " else print "infixr "; if i div 2 > 0 then (print (i div 2); print " ") else ()); ! printSequence " " printSym ops; ! newline()) Status: fixed in 0.75 --------------------------------------------------------------------------- 468. extra comma in printing unit record Submitter: Thomas Yan (Cornell) Date: 11/18/91 Version: 0.75 Severity: minor Problem: Extra comma in printing unit record: Transcript: - val {...} = (); std_in:2.1-2.14 Warning: binding contains no variables {,...} = ... Status: fixed in 0.85 --------------------------------------------------------------------------- 469. infix precedence bound Submitter: Thomas Yan (Cornell) Date: 11/18/91 Version: 0.75 Severity: minor Problem: Infix declaration allows values greater than 9: Transcript: - infix 10 +; infix 10 + Status: fixed in 0.90 --------------------------------------------------------------------------- 470. top-level continuations Submitter: Francis.Dupont@inria.fr Date: Sat Nov 23 16:49:36 MET 1991 Version: 0.75 System: all systems (tested on Sun4/75 running SunOS4.1.1) Severity: major Problem: the typing of toplevel continuation is incorrect Code: see later Transcript: see later Comments: this bug cannot be corrected because toplevel continuations (implied by call/cc) are not compatible with SML type system (see all the literature on this topics, for intance my PhD thesis if you can read French...) Fix: Easy : drop call/cc (use limited static continuations) The code and the bug : % sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - datatype foo = None | Kont of int cont; datatype foo con Kont : int cont -> foo con None : foo - val x = ref None; val x = ref None : foo ref - callcc (fn k => (x := Kont k; 1)); val it = 1 : int - val y = (fn (Kont k) => k) (!x); std_in:5.10-5.25 Warning: match not exhaustive Kont k => ... val y = cont : int cont - val f = (throw y : int -> bool); val f = fn : int -> bool - f 1; val it = 1 : int Francis.Dupont@inria.fr PS : a variant of this bug is described in report 145 "stale top-level continuations cause type bugs" (cf doc/bugs/masterbugs) and its status is "fixed in 0.49" (sorry, it cannot be fixed) ! Status: fixed in 0.82 (but further investigation is warranted) --------------------------------------------------------------------------- 471. allocating large arrays Submitter: Mike Crawley <mjc@abstract-hardware-ltd.co.uk> Date: 11/26/91 Version: 0.75 Severity: serious Problem: Sometimes it will crash when allocating very large arrays. Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - open Array; open Array - infix 7 sub; infix 7 sub - fun Sieve n = let val A = array (n,false) ; fun set i di = if i < n then (update (A,i,true) ; set (i+di) di ) else () ; fun get 1 acc = acc | get i acc = get (i-1) (if A sub i then acc else i :: acc) ; fun siv i = if i >= n then [] else if (A sub i) = false then (set (i+i) i ; siv (i+1)) else siv (i+1) ; in siv 2 ; get (n-1) [] end ; val Sieve = fn : int -> int list - Sieve 3628800; Segmentation fault (core dumped) But it works if I do it more gently. Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - open Array; open Array - infix 7 sub; infix 7 sub - fun Sieve n = let val A = array (n,false) ; fun set i di = if i < n then (update (A,i,true) ; set (i+di) di ) else () ; fun get 1 acc = acc | get i acc = get (i-1) (if A sub i then acc else i :: acc) ; fun siv i = if i >= n then [] else if (A sub i) = false then (set (i+i) i ; siv (i+1)) else siv (i+1) ; in siv 2 ; get (n-1) [] end ; val Sieve = fn : int -> int list - Sieve 1000000; [Increasing heap to 2952k] [Increasing heap to 5792k] [Increasing heap to 8192k] [Major collection... 63% used (412372/652688), 250 msec] [Increasing heap to 12544k] val it = [2,3,5,7,11,13,17,19,23,29,31,37,...] : int list - Sieve 3628800; [Major collection... 25% used (1354396/5356616), 880 msec] [Increasing heap to 14944k] [Major collection... 99% used (1354396/1354396), 870 msec] [Increasing heap to 24408k] [Major collection... 99% used (1354396/1354396), 860 msec] [Increasing heap to 38600k] [Increasing heap to 42544k] val it = [2,3,5,7,11,13,17,19,23,29,31,37,...] : int list - Comments: This occurs in Standard ML of New Jersey, Version 75, November 11, 1991 Standard ML of New Jersey, Version 0.73, 10 September 1991 Standard ML of New Jersey, Version 0.66, 15 September 1990 so I think it is the memory allocation rather than the new Array structure. Status: fixed in 0.84 --------------------------------------------------------------------------- 472. growing heap Submitter: Simon Finn <simon@abstract-hardware-ltd.co.uk> Date: 11/26/91 Version: 0.75 System: ? Severity: serious Problem: SML/NJ version 0.75 seems to have a problem when asked to grow the heap by a large factor. Transcript: this works: Perky% /ml/njml/mlsave.75/src/sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - val y = Array.array (1000000,true); [Increasing heap to 4020k] [Increasing heap to 8192k] [Major collection... 98% used (409232/414048), 260 msec] [Increasing heap to 12884k] val y = prim? : bool array - val x = Array.array (2000000,true); [Increasing heap to 16636k] [Major collection... 99% used (4409484/4411876), 1770 msec] [Increasing heap to 31412k] val x = prim? : bool array but this doesn't: - Perky% !! /ml/njml/mlsave.75/src/sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - val x = Array.array (2000000,true); Segmentation fault (core dumped) Perky% Status: fixed in 0.84 --------------------------------------------------------------------------- 473. inadequate error message Submitter: George Otto (ptah!otto) Date: 11/27/91 Version: 0.75? Severity: minor Problem: I put some ML datatype definitions into a file and then brought them into ML using the command use "file"; I got back the error message "duplicate constructor" with no other information. Couldn't this be more helpful and mention the name of the constructor it is reporting about? Status: fixed in 0.91 (dbm) --------------------------------------------------------------------------- 474. compiler bug: patType -- unexpected pattern Submitter: John Reppy Date: 12/6/91 Version: 0.75 Severity: minor Problem: Compiler bug: patType -- unexpected pattern Code: (* extract the draw_cmd, id and depth of a drawable *) fun infoOfDrawable (DRAWABLE{draw_cmd, DWIN w}) = let val WIN{id, scr_depth=SCRDEPTH{depth, ...}, ...} = w in {draw_cmd=draw_cmd, id=id, depth=depth} end | infoOfDrawable (DRAWABLE{draw_cmd, DPM pm}) = let val PM{id, scr_depth=SCRDEPTH{depth, ...}, ...} = pm in {draw_cmd=draw_cmd, id=id, depth=depth} end Transcript: window/draw.sml:16.51 Error: syntax error: inserting AS window/draw.sml:21.43-21.44 Error: syntax error: inserting AS Error: Compiler bug: patType -- unexpected pattern Comments: couldn't isolate small example (same as #515) Status: fixed in 0.83 --------------------------------------------------------------------------- 475. LOOKUP exception from mllex (see also 510, 516) Submitter: Markus Freericks, mfx@cs.tu-berlin.de Date: 12.12.91 Version: Standard ML of New Jersey, Version 75, November 11, 1991 System: Sparc Severity: quite minor Problem: When I use a regular expression that isn't defined, I get an unhelpful exception LOOKUP. This exception is not mentioned in lexgen.doc, and there is no indication as to where the problem occurs in the input file. Code: (* bug *) %% %% {xxx} => {()}; Transcript: mfx@marx [77]% sml-lex bug ? sml-lex: uncaught exception LOOKUP or - use "lexgen.sml"; [opening lexgen.sml] lexgen.sml:1127.5-1131.57 Warning: match not exhaustive (true,129) => ... (true,256) => ... (false,129) => ... (false,256) => ... lexgen.sml:876.2-895.10 Warning: match not exhaustive (nil,nil) => ... (a :: a',b :: b') => ... lexgen.sml:854.19-855.48 Warning: match not exhaustive 1 => ... 2 => ... 3 => ... lexgen.sml:813.9-813.55 Warning: match not exhaustive (tl,el) :: r => ... functor RedBlack : <sig> signature LEXGEN = sig val lexGen : string -> unit end structure LexGen : LEXGEN [closing lexgen.sml] val it = () : unit - LexGen.lexGen "bug"; uncaught exception LOOKUP Comments: Being what could be called a 'naive user', I first thought my installation of SML and/or lexgen.sml to be in error. The warnings encountered when loading lexgen.sml added to this impression. Fix: A change to the doc should be enough; the error in the input file is easy enough to find when one knows what to search for. Status: fixed in 0.91 (Tarditi) --------------------------------------------------------------------------- 476. sml-lex Submitter: Denys Duchier <dduchier@csi.UOttawa.CA> Date: 12/11/91 Version: 0.75 Severity: minor Problem: sml-lex (with SML V75) produces a lexer that contains D and T states when I use the special character $. Here is the source: Code: datatype lexresult = EOF; fun eof () = EOF; %% %% ";".*$ => (lex()); Comments: the rule is meant to parse a lisp-style comment. Andrew sez: I'm not sure that this is really a bug. Perhaps the documentation needs to be changed? Status: fixed in 0.91 (Tarditi) --------------------------------------------------------------------------- 477. duplicate specifications through include Submitter: Nick Rothwell Date: 21 Oct 91 Version: 0.73 Severity: minor Problem: I enclose a short-ish (40 line) program. It compiles under poplog and one version of poly. It fails under another version of poly and with different errors under two versions of SML/NJ. By my reckoning, the program is legal SML. Code: signature MONO_SET = sig type Element type Set type T sharing type T = Set end; functor MonoSet(type T): MONO_SET = struct abstype Set = Set of T list with type Element = T type T = Set end end; signature INPUT_VAR = sig type InputVar type InputVarSet include MONO_SET sharing type Element = InputVar and type Set = InputVarSet type T sharing type T = InputVar end; functor InputVar(): INPUT_VAR = struct datatype InputVar = INPUT_VAR of string local structure S = MonoSet(type T = InputVar) in open S type InputVarSet = Set end type T = InputVar end; Transcript: X.sml:25.10 Error: duplicate specifications for type constructor T in signature Comments: a deliberate divergence from the Definition. Status: not a bug ---------------------------------------------------------------------- 478. order of type definitions in withtype clause Submitter: Andrew Appel Date: 10/11/91 Version: 0.73 Severity: minor Problem: Type definitions in withtype clause have to be ordered properly. Code: datatype foo = T withtype a = b and b = foo Comments: I think this is correct. Have to check Definition. Status: not a bug ---------------------------------------------------------------------- 479. Boxity exception in vector_n Submitter: Andrew Koenig Date: 10/22/91 Version: ? Severity: major Problem: Applying vector_n with index out of bounds yields Boxity exception. Transcript: - open Vector; open Vector - infix 9 sub; infix 9 sub - val x = vector_n(10,[1,2,3]); val x = - : int vector - length(x); val it = 10 : int - x sub 0; val it = 1 : int - x sub 1; val it = 2 : int - x sub 2; val it = 3 : int - x sub 3; val it = 8 : int - x sub 4; val it = uncaught exception Boxity Comments: vector_n was not supposed to be exported. Status: fixed in 0.75 ---------------------------------------------------------------------- 480. Exit status of makeml is 1. Submitter: David Tarditi Date: 10/23/91 Version: 0.75? Severity: minor Problem: makeml almost always returns an exit status of 1, which indicates failure. This is because as a shell program it returns the value of its last command, which is an if-statement that almost always "fails" (the value of the if-statement is the last simple command that it executes, which is a test that fails; there is no "else" clause to execute). This creates problems for me when I use a makefile that invokes makeml to build sml images. Could you make the last statement in makeml "exit 0" ? Comments: Status: fixed in 0.89 ---------------------------------------------------------------------- 481. redeclared constructors Submitter: Mike Crawley <mjc@abstract-hardware-ltd.co.uk> Date: 10/28/91 Version: 0.73 Severity: minor Problem: SML/NJ 0.73 does not accept the following valid ML program Code: signature S = sig datatype a = A | B of string ; datatype b = B | C ; end ; functor F(S:S) = struct open S ; fun matchA A = true | matchA _ = false ; fun matchB B = true | matchB _ = false ; fun matchC C = true | matchC _ = false ; end ; structure S = F ( datatype a = A | B of string ; datatype b = B | C ) ; Status: open ---------------------------------------------------------------------- 482. "constant" unary type abbreviations in signature matching Submitter: Mike Crawley <mjc@abstract-hardware-ltd.co.uk> Date: 10/28/91 Version: 0.73 Severity: significant Problem: Poly/ML allows this; SML/NJ 0.73 doesn't It all depends whether or not you expand the type-abbreviation t when you match the datatype d. Code: signature A = sig eqtype 'a t datatype d = C | D of int t end; structure Z = struct type 'a t = bool datatype d = C | D of bool t end; structure X : A = Z; Status: fixed at least as early as 0.80 ---------------------------------------------------------------------- 483. lexgen compilation blowup Submitter: Lie Ma, ma@cs.pdx.edu Date: 10/29/1991 Version: SML Ver.0.66 System: Sun Sparc Code: lexgen.sml Ver. 1.3, Dec'89 Encl: typescript Problem: I'm using lexgen to write a lexer for a formal specification language. According to the manual, I should use lexgen.sml in the following way: quote: Running ML-Lex Use "lexgen.sml"; this will create a structre LexGen. The function LexGen.lexGen creates a program for a lexer from an input specification. It takes a string argument -- the name of the file containing the input spacification. The output file name is determined by appending ".sml" to the input file name. end{quote} I got the extremly poor performance when I tried to use "lexgen.sml". I tried on two Suns, both taking appr. 25 to 28 minutes to evaluate "lexgen.sml". The maximum heap was about 16 MB. The process was so huge that the system speeded donw and I had to kill it in most cases. And once other user even could not run latex within emacs. I want to know whether it is usual. If not, it's caused by ML or "lexgen.sml"? Thank you to your attention to this. Your prompt reply will be appreciated. Status: fixed in 0.89 ---------------------------------------------------------------------- 484. interrupt is buggy (same as 511, 518) Submitter: Mike Crawley Date: 10/29/91 Version: 0.73 System: Sparc/SunOS Severity: major Problem: I have been able to repeat the following bug a number of times. Pressing ^C to interrupt sml while it is busy can sometimes crash it. The saved image I was using was 10MB at the time. ^C SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0x9dd8) Transcript: Comments: This is a very mysterious bug that has been around for a while. The "0x9de3bfc0 @ 0x9dd8" means that the signal handler received a SIGEMT signal with the PC = 0x9dd8 and the instruction at that address being "save %sp,-0x40,%sp." Under my reading of the documentation, this should never occur in SunOS. The address 0x9dd8 is interesting, since it is the address of an assembly routine used to force a GC trap after a signal (such as ^C), but I don't understand how the sigcontext program counter gets that value. [John Reppy] Status: open ---------------------------------------------------------------------- 485. structure manipulation bombs Submitter: Tim Freeman <tsf@cs.cmu.edu> Date: Thu Oct 31 15:32:46 1991 Version: 0.74 System: Sun 4 running some version of Mach Severity: minor Problem: With some manipulations of structures, raising unhandled exceptions causes SML to bomb. Code: bug3.sml contains: structure Util = struct exception Bug of string end structure InstProto = struct structure U = Util structure S = struct end end open InstProto ; raise U.Bug "hi" Transcript: % sml Standard ML of New Jersey, Version 0.74, 10 October, 1991 Prerelease version. Arrays have changed; see doc/NEWS val it = () : unit - use "bug3.sml"; [opening bug3.sml] structure Util : sig exception Bug of string end structure InstProto : sig structure S : ... structure U : ... end open InstProto SIGILL code 0x7 % Comments: Earlier during the process of narrowing down this bug, it was saying uncaught exception random binary garbage (except you have to imagine the string "random binary garbage" replaced by random binary garbage) instead of getting the SIGILL trap. Status: fixed in 0.84 ---------------------------------------------------------------------- 486. Regbind exception (same as bug 380?) Submitter: jont@harlqn.co.uk Date: 31/10/91 Version: SML of NJ version number, 0.66 System: Sun 4/330 with SunOS 4.1.1 Severity: critical Problem: The code generation phase blows up with an uncaught exception Regbind Code: (* _testreals.sml the functor (used to be) *) (* Copyright (c) 1991 Harlequin Ltd. *) fun div2 _ = let val new_y = if 0 mod 2 = 0 then "0" else chr(ord "0" + 1) in div2 [] end Transcript: sml66 Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use"../main/_testreals.sml"; [opening ../main/_testreals.sml] [closing ../main/_testreals.sml] uncaught exception Regbind Comments: This is the second time I have encountered this problem. The first time I was unable to produce a small example, and it later went away for reasons which were never clear. However, this time it cropped up in a functor which was only 80 lines at the time, and I was able to whittle it down to the above rather useless function. Probably same as bug #380. Status: fixed in 0.84 ---------------------------------------------------------------------- 487. clumsy memory exhaustion Submitter: Andy Koenig Date: 11/7/91 Version: 0.74 System: Sparc Severity: minor Problem: SML-NJ is not very nice about handling memory exhaustion. Transcript: [boojum] sml Standard ML of New Jersey, Version 0.74, 10 October, 1991 Prerelease version. Arrays have changed; see doc/NEWS val it = () : unit - fun f x = f(0::x); val f = fn : int list -> 'a - f nil; [Increasing heap to 3164k] [Increasing heap to 4452k] [Increasing heap to 5456k] [Major collection... [Increasing heap to 8192k] 76% used (3427160/4508104), 2610 msec] [Increasing heap to 13192k] [Major collection... 49% used (4497848/8999168), 4600 msec] [Increasing heap to 26380k] [Major collection... 49% used (8999168/18002072), 9250 msec] [Increasing heap to 27204k] [Major collection... [Increasing heap to 27620k] [Increasing heap to 27776k] [Increasing heap to 27860k] [Increasing heap to 27880k] Warning: can't increase heap Ran out of memory[boojum] Comments: While I do ultimately expect some kind of drastic termination, I do **NOT** expect to be unceremoniously dumped out of ML back into the Shell. A more reasonable strategy might be to preallocate a chunk of memory to be used as secondary storage while recovering from exhaustion of primary storage. That, at least, would allow for a return to top level and associated garbage collection, which, in many cases, would allow interactive execution to resume. Incidentally, this example was run on a Sparcstation with 64 megabytes of physical memory and no limit on process size that I know of. I don't know why it gave up the ghost at 28 megabytes -- do you? Status: open ---------------------------------------------------------------------- 488. wrong types in pervasives Submitter: Thomas Yan Date: 8/21/91 Version: 0.71 Severity: minor Problem: bugs in the pervasive environment Transcript: Standard ML of New Jersey, Version 0.71, 23 July 1991 val it = () : unit - Array.tabulate; val it = fn : 'a * (int -> '1b) -> '1b array - String.chr; val it = fn : int -> 'a - Status: Fixed in 0.75 ---------------------------------------------------------------------- 489. exportFn image size too large Submitter: Andy Koenig Date: 11/17/91 Version: 0.75 System: Sparc Severity: significant Problem: On a Sparc, here's the text and data space used by the executable produced by the following program (with an ML build with noshare): exportFn ("a.out", fn _ => print "Hello world\n"); Version text data 0.66 57344 188416 pre-74 81920 425984 75 81920 294912 Evidently some of the memory leaks in 0.66 have been fixed but not all. Anoither example from John Reppy: (sml-export was made with the -pervshare option) <jhr@bat> sml-export Standard ML of New Jersey, Version 0.89, September 4, 1992 val it = () : unit - exportFn("foo", fn _ => ()); [Major collection... 25% used (842428/3366736), 430 msec] [Major collection... 66% used (560264/844136), 310 msec] <jhr@bat> size foo text data bss dec hex 241664 614400 0 856064 d1000 <jhr@bat> size sml-export text data bss dec hex 241664 3416064 0 3657728 37d000 Fix: Environment refs (pervasiveEnvRef, topLevelEnvRef) were added to Hooks and cleared on export. Changed files boot/perv.sml and boot/system.sig. Status: fixed in 0.93c (awa,dbm) ---------------------------------------------------------------------- 490. function has bad type in pervasives Submitter: Lal Geoge Date: 11/20/91 Version: 0.75 Severity: significant Problem: ceiling has wrong type Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes - ceiling; val it = fn : real -> 'a - Status: fixed in 0.76 ---------------------------------------------------------------------- 491. memory leak Submitter: Nevin Heintze (nch@cs.cmu.edu) Date: Wed Nov 20 1991 Version: 0.75 System: sparc1, pmax, sun3 Mach 2.6 #5.1(CS8f): Wed Sep 11 14:39:14 EDT 1991; CS8/STD+WS Severity: major Problem: garbage collection when rebuilding structures (stuff in old structures does not seem to be reclaimed). Code: signature MEM_HOG = sig val X : int Array.array end functor Mem_hog() : MEM_HOG = struct val X = Array.array(200000, 42) end structure Mem_hog : MEM_HOG = Mem_hog(); open Mem_hog; structure Mem_hog : MEM_HOG = Mem_hog(); open Mem_hog; (* etc... (Following transcript uses 8 functor applications) *) Transcript: Script started on Wed Nov 20 13:54:15 1991 [alonzo] % sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "mem.sml"; [opening mem.sml] [Increasing heap to 3174k] signature MEM_HOG = sig val X : int array end functor Mem_hog : <sig> structure Mem_hog : MEM_HOG open Mem_hog [Increasing heap to 3990k] structure Mem_hog : MEM_HOG [Increasing heap to 4094k] open Mem_hog structure Mem_hog : MEM_HOG open Mem_hog [Major collection... [Increasing heap to 6486k] 98% used (2814944/2866068), 1930 msec] [Increasing heap to 10022k] structure Mem_hog : MEM_HOG open Mem_hog structure Mem_hog : MEM_HOG open Mem_hog structure Mem_hog : MEM_HOG open Mem_hog structure Mem_hog : MEM_HOG [Major collection... [Increasing heap to 17126k] 73% used (4412384/6025784), 3670 msec] [Increasing heap to 17646k] open Mem_hog structure Mem_hog : MEM_HOG open Mem_hog [closing mem.sml] val it = () : unit - [alonzo] % exit script done on Wed Nov 20 13:54:43 1991 Comments: I have been running into this problem for a while now in some program analysis implementation work, but was not sure where the problem was. After about 3-4 rebuilds of my system I usually have to start another core image. The general problem occurs on sparc, sun4 and pmax machines; the specific code given above has been tried on a sparc (24MB) and a pmax (64MB?). If the "open Mem_hog" is removed, then the problem goes away. The problem is not specific to arrays; for example if X is bound to a list of a couple of thousand elements instead of an array, then similar behaviour occurs. Status: fixed in 0.89 ---------------------------------------------------------------------- 492. compiler bug from sharing Submitter: David Tarditi Date: 7/19/91 Version: 0.70 Severity: major Problem: This code causes a compiler bug in version 0.70. It should be an interesting test case in the future. Code: (* This code shows that we'll need to augment structure instantiation arrays during functor abstraction to include structures which are not in the signature, but which have views that are in the signature. *) signature S0 = sig type u end signature S1 = sig type t val v : t end (* define a structure A, but export only views of A *) functor F1() : sig structure B : S0 structure C : S1 end = struct structure A = struct datatype u = U datatype t = T val v = T end structure B : S0 = A structure C : S1 = A end structure D = F1() (* the definitional sharing constraint implies that C.t = D.C.t, but we won't know this unless we keep the origin of D.B around.*) functor F2(A : sig structure C : S1 sharing D.B = C end) : sig val v : A.C.t end = struct val v = D.C.v end Status: fixed in 0.84 ---------------------------------------------------------------------- 493. Compiler bugs from bad include specs Submitter: Bruce Esrig Date: 7/19/91 Version: ? Severity: major Problem: Compiler bug from include specs Code: (* Sigs.sml -- experiment with signatures and sharing *) (* this is accepted *) signature X' = sig datatype 'a Opt = None | Some of 'a end signature Y' = sig datatype 'a Opt = None | Some of 'a end signature Z' = sig include X' include Y' end; (* this fails *) signature X' = sig datatype 'a Opt = None | Some of 'a end signature Y' = sig include X' end (* signature Z' = sig include X' include Y' end *) (* std_in:0.0 Compiler Bug: Signs.abstractSig.abstractType 2 *) (* signature W' = sig include X' include Y' sharing type X'.Opt = Y'.Opt end *) (* std_in:0.0 Compiler Bug: Signs.abstractSig.abstractType 2 *) signature X' = sig type opt end signature Y' = sig type opt end (* signature Z' = sig include X' include Y' sharing type X'.opt = Y'.opt end *) (* std_in:2.20-2.70 Error: unbound structure id in sharing specification: X' *) (* How do I build a signature which brings a shared type to top level? *) signature Z' = sig structure X : X' structure Y : Y' sharing type X.opt = Y.opt open X end structure Z : Z' = struct structure X = struct type opt = int end structure Y = struct type opt = int end open X end; (* structure Z : sig structure X : sig...end structure Y : sig...end end *) (* 5 : Z.opt; *) (* std_in:10.5-10.9 Error: unbound type in structure: opt *) Status: fixed in 0.84 ---------------------------------------------------------------------- 494. bogus gc message Submitter: Bob Harper Date: 12/16/91 Version: 0.75 Severity: minor Problem: negative number in "[Increasing heap to -12217k]" message Transcript: [reading .../front/printback.sml] [Major collection... [Increasing heap to 8110k] [Increasing heap to 7942k] [Increasing heap to 7438k] [Increasing heap to 5926k] [Increasing heap to 1390k] smlsg: could not sbrk, return = 1 [Increasing heap to -12217k] *** NB 48% used (2767236/5647472), 2570 msec] [Increasing heap to 8270k] [writing .../.@sys/printback.sml.bin... done] [closing .../front/printback.sml] Status: open -------------------------------------------------------------------- 495. inaccurate emacs info file Submitter: dan@math.uiuc.edu Date: 12/26/91 Version: 75 Severity: minor Problem: From the IO node in the emacs info file "sml" val execute : string -> instream * outstream From the program - execute; val it = fn : string * string list -> instream * outstream Fix: edit the file "sml" to give the correct declaration for "execute" Status: fixed (in /usr/local/sml/75/lib/emacs/info/sml) ---------------------------------------------------------------------- 496. incorrect defn of dec in fastlib Submitter: Stephen Adams, S.R.Adams@ecs.soton.ac.uk Date: 3 Jan 1992 Version: 0.75 Severity: curiosity Problem: Curious code in compiler source I have been looking in the compiler source and I discovered a small bug: Code: (* cpsopt.sml * * Copyright 1989 by AT&T Bell Laboratories *) functor CPSopt(val maxfree : int) : sig val reduce : CPS.function * System.Unsafe.object option * bool -> CPS.function end = struct structure Fastlib = struct structure Ref = struct open Ref fun inc r = r := !r + 1 fun dec r = r := !r + 1 (* this is the worrying bit!*) end Comment: dec is used but only in the function `unescapeargs'. I guess that it should be fixed before it causes any grief. Status: Fixed in 0.75 ---------------------------------------------------------------------- 497. ML-Yacc doesn't open Array Submitter: Lie Ma, ma@cs.pdx.edu Date: 12/26/91 Version: SML Ver.77 System: SUN Sparc Code: base.sml Encl: typescript Problem: Error found when loading base.sml, while no problem using SML Ver.66. Or, is there new version of smlyacc corporated with the new version of SML? ---------------------- Typescript ---------------------- Script started on Thu Dec 26 22:45:01 1991 warning: could not update utmp entry antares% cat makepaqrser.sml" "; Unmatched ". antares% cat makeparser.sml (* ------------------------ FILE: makeparser.sml ---------------------------- Author: Lie Ma 12/10/1991 Usage: Call the files "spec.grm.sig", "spec.grm.sml" (generated by "smlyacc.sml" according to "spec.grm") and "spec.lex.sml" (gnerated by "lexgen.sml" according to "spec.lex"). Then use structure "SpecLrVals", "SpecLex" and "SpecParser" to generate the parser. Call: spec.grm.sig, spec.grm.sml, spec.lex.sml Input: nothing Output: parser -------------------------------------------------------------------------- *) use "YACC/base.sml"; (* laod the common modules *) use "spec.grm.sig"; (* load grammar signature file *) use "spec.lex.sml"; (* load lexer program file *) use "spec.grm.sml"; (* load grammar program file *) (* --------- define structures ------------ *) structure SpecLrVals = SpecLrValsFun(structure Token = LrParser.Token); structure SpecLex = SpecLexFun(structure Tokens = SpecLrVals.Tokens); structure SpecParser = Join(structure ParserData = SpecLrVals.ParserData structure Lex=SpecLex structure LrParser=LrParser); (* ----------- function parse to read file and parse it -------------- *) val parse = fn s => let val dev = open_in s val stream = SpecParser.makeLexer(fn i => input(dev,i)) val _ = SpecLex.UserDeclarations.pos:=1 val error = fn(e,i: int,_) => output(std_out, s ^ "," ^ " line "^ (makestring i) ^ ", Error: " ^ e ^ "\n") in SpecParser.parse(30,stream,error,()) before close_in dev end val keybd = fn () => let val dev = std_in val stream = SpecParser.makeLexer (fn i => input_line dev) val _ = SpecLex.UserDeclarations.pos:=1 val error = fn(e,i: int,_) => output(std_out, "std_in, line "^ (makestring i) ^ ", Error: " ^ e ^ "\n") in SpecParser.parse(0,stream,error,()) end antares% sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - " use "makeparser.sml"; [opening makeparser.sml] [opening YACC/base.sml] signature STREAM = sig type 'a stream val streamify : (unit -> '1a) -> '1a stream val cons : '1a * '1a stream -> '1a stream val get : '1a stream -> '1a * '1a stream end signature LR_TABLE = sig datatype state con STATE : int -> state datatype term con T : int -> term datatype nonterm con NT : int -> nonterm datatype action con ACCEPT : action con ERROR : action con REDUCE : int -> action con SHIFT : state -> action type table val numStates : table -> int val describeActions : table -> state -> (term * action) list * action val describeGoto : table -> state -> (nonterm * state) list val action : table -> state * term -> action val goto : table -> state * nonterm -> state val initialState : table -> state exception Goto of state * nonterm val mkLrTable : {actions:((term * action) list * action) list,gotos:(nonterm * state) list list,initialState:state,numStates:int} -> table end signature TOKEN = sig structure LrTable : ... datatype ('a,'b) token con TOKEN : LrTable.term * ('a * 'b * 'b) -> ('a,'b) token val sameToken : ('a,'b) token * ('a,'b) token -> bool end signature LR_PARSER = sig structure Stream : ... structure LrTable : ... structure Token : ... exception ParseError val parse : {arg:'a,ec:{error:string * '1c * '1c -> unit,errtermvalue:LrTable.term -> '1b,is_keyword:LrTable.term -> bool,noShift:LrTable.term -> bool,preferred_insert:LrTable.term -> bool,preferred_subst:LrTable.term -> LrTable.term list,showTerminal> :LrTable.term -> string,terms:LrTable.term list},lexer:('1b,'1c) Token.token Stream.stream,lookahead:int,saction:int * '1c * (LrTable.state * ('1b * '1c * '1c)) list * 'a -> LrTable.nonterm * ('1b * '1c * '1c) * (LrTable.state * ('1b * '1c * '1c)) list,ta> ble:LrTable.table,void:'1b} -> '1b * ('1b,'1c) Token.token Stream.stream sharing Token.LrTable = LrTable end signature LEXER = sig structure UserDeclarations : ... val makeLexer : (int -> string) -> unit -> (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token end signature ARG_LEXER = sig structure UserDeclarations : ... val makeLexer : (int -> string) -> UserDeclarations.arg -> unit -> (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token end signature PARSER_DATA = sig type pos type svalue type arg type result structure LrTable : ... structure Token : ... structure Actions : ... structure EC : ... val table : LrTable.table sharing LrTable = Token.LrTable end signature PARSER = sig structure Token : ... structure Stream : ... exception ParseError type pos type result type arg type svalue val makeLexer : (int -> string) -> (svalue,pos) Token.token Stream.stream val parse : int * (svalue,pos) Token.token Stream.stream * (string * pos * pos -> unit) * arg -> result * (svalue,pos) Token.token Stream.stream val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> bool end signature ARG_PARSER = sig structure Token : ... structure Stream : ... exception ParseError type arg type lexarg type pos type result type svalue val makeLexer : (int -> string) -> lexarg -> (svalue,pos) Token.token Stream.stream val parse : int * (svalue,pos) Token.token Stream.stream * (string * pos * pos -> unit) * arg -> result * (svalue,pos) Token.token Stream.stream val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> bool end structure Stream : STREAM YACC/base.sml:340.14-340.16 Error: unbound variable or constructor sub YACC/base.sml:342.10-342.25 Error: operator and operand don't agree (tycon mismatch) operator domain: 'Z array operand: error -> int -> 'Y in expression: length a YACC/base.sml:342.26 Error: overloaded variable "-" cannot be resolved YACC/base.sml:395.36-395.38 Error: unbound variable or constructor sub YACC/base.sml:395.28-395.45 Error: operator is not a function operator: (int array * int) array in expression: action bogus YACC/base.sml:402.26-402.28 Error: unbound variable or constructor sub YACC/base.sml:402.20-402.35 Error: operator is not a function operator: int array array in expression: goto bogus YACC/base.sml:409.45-409.47 Error: unbound variable or constructor sub YACC/base.sml:421.53-421.55 Error: unbound variable or constructor sub YACC/base.sml:418.27-418.48 Error: operator and operand don't agree (tycon mismatch) operator domain: 'Z array operand: error -> int -> int in expression: length row YACC/base.sml:421.40-421.62 Error: operator is not a function operator: (int array * int) array in expression: action bogus YACC/base.sml:418.46 Error: overloaded variable "-" cannot be resolved YACC/base.sml:427.29-427.31 Error: unbound variable or constructor sub YACC/base.sml:431.49-431.51 Error: unbound variable or constructor sub YACC/base.sml:427.14-427.37 Error: operator is not a function operator: int array array in expression: goto bogus YACC/base.sml:447.5-447.15 Error: unbound variable or constructor arrayoflist YACC/base.sml:449.5-449.15 Error: unbound variable or constructor arrayoflist YACC/base.sml:450.17-450.27 Error: unbound variable or constructor arrayoflist YACC/base.sml:453.14-453.24 Error: unbound variable or constructor arrayoflist [closing YACC/base.sml] [closing makeparser.sml] - ^Dantares% ^D script done on Thu Dec 26 22:46:17 1991 Status: fixed in 0.84 ---------------------------------------------------------------------- 498. bad function type in perv.sig Submitter: Embden Gansner Date: 1/7/92 Version: ? Severity: significant Problem: The BITS signature in perv.sig should have val notb : int -> int instead of val notb : int * int -> int Status: fixed in 0.81 ---------------------------------------------------------------------- 499. execute broken Submitter: David Spooner (spoonerd@.cpsc.ucalgary.ca) Date: 1/7/92 Version: 0.75 System: ? Severity: major Problem: No output availabe from execute. Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () :unit - val (instr,outstr) = execute ("ls", []); val instr = - :instream val outstr = - :outstream - input (instr, 5); val it = "" :string - can_input instr; val it = 0 :int Fix: (luochen@shade.Princeton.EDU (Luoqi Chen)) I believe the problem is in the runtime routine, ml_exec(), it calls execve(2) instead of execvp(3), so it won't look up in the PATH for the command. Try "/bin/ls" instead. The fix is simple, change the line (line 1238 of src/runtime/cfuns.c) execve (cmd, argv, envp); to { extern char **environ = envp; execvp(cmd, argv);} Status: fixed in 0.86 ---------------------------------------------------------------------- 500. memory leak Submitter: Kjeld H. Mortensen, metasoft!kjeld@uunet.UU.NET, (617) 576.6920 x 22 Date: 1/7/92 Version: 0.75 System: SUN OS 4.1.1, ram 32Mb, swap 103Mb, and HPUX 8.0, ram 32Mb, swap 70Mb. Severity: major Problem: During use of the extended compiler we see a significant slowdown of this process when using v0.75 of SML/NJ (a factor 2 over a time period of 15 minutes reasonable heavy use, and doesn't seem to stop there). Observations: 1) We see absolutely no slow down when using v0.62 of SML/NJ on the Sun4 (haven't been able to succesfully compile this version on the HP9000 though). 2) We see significant slow down when using v0.75 of SML/NJ on both the Sun4 and HP9000. (In spite of the slow down, the compiler process gets more and more CPU-time.) 3) Since we use the same ML-code in both cases 1) and 2), I'm lead to conclude that it must be a problem in the SML/NJ system v0.75. Example: Unfortunately I haven't been able to reproduce the phenomenon for a reasonable small example. Followup: >...By the way, is your slow-down program mostly compiling things, or executing >compiled code? It is mostly executing compiled code. I made some further investigations regarding the heap size. Each of the experiments performed, make up the same amount of work for the ML process (work is measured in units of what I call "steps"). In the following table, "MEM-INC" is calculated using numbers from the first and the last major collection. Let the output from the two major collections have the format: [Major collection... <P1>% used (<MUSED1>/<MTOT1>), <T1> msec] [Major collection... <Pn>% used (<MUSEDn>/<MTOTn>), <Tn> msec] The numbers in "MEM-INC" then have the format: <MUSEDn>-<MUSED1>/<MTOTn>-<MTOT1>, "/" not to be confused with division. The numbers in "Work" are only there to show that the compiler in each experiment, did the same amount of computations. Machine configurations: Sun4 , SUN OS 4.1.1, ram 32Mb, swap 103Mb, and HP9000s400, HPUX 8.0 , ram 32Mb, swap 70Mb. Machine | SML/NJ | Work/steps | MEM-INC/bytes | Number of major coll. -----------+--------+------------+---------------+---------------------- Sun4 | v0.62 | 203 | 18292/179960 | 4 Sun4 | v0.75 | 201 | 425120/926324 | 12 HP9000s400 | v0.75 | 202 | 517352/931376 | 40 Comment: [dbm] This was probably fixed by restoring environment cleanup (in 0.82). Status: fixed in 0.84 ---------------------------------------------------------------------- 501. out of date yacc example code Submitter: Andy Koenig Date: 1/11/92 Version: ? Severity: minor Problem: The calc.grm.sig, calc.grm.sml, and calc.lex.sml file in mlyacc/examples/calc needs to be updated. Rerun ml-yacc and ml-lex on the appropriate files. Fix: In the calc directory are the following files: README calc.grm calc.grm.desc calc.grm.sig calc.grm.sml calc.lex calc.lex.sml join.sml load.sml Saying sml-lex calc.lex rebuilds calc.lex.sml; saying sml-yacc calc.grm rebuilds calc.grm.* That should be done in the distribution directories so that people will get the right versions. [from Dave Tarditi:] The directory tools/mlyacc/examples contains some files which need to be regenerated by the new versions of the parser and lexer generator. You need to regenerate the files examples/calc/calc.grm.sml, examples/calc.lex.sml by running the parser generator on calc.grm and the lexer generator on calc.lex. Please remove the file examples/fol/fol.lex.sml. Status: fixed in 0.91 (Tarditi) ---------------------------------------------------------------------- 502. zombie sml processes Submitter: Stephen Adams <S.R.Adams@ecs.southampton.ac.uk> Date: 1/13/92 Version: 0.66, 0.75 System: SunOS 4.1, sparc Severity: minor Problem: SML processes don't die if you log out Code: any running sml process Comment: We use NJ-SML for teaching and research. A common problem is if a user logs out (by selecting `exit' in X-windows, for example) the sml proces doesnt die, but sits there consuming cpu cycles (often > 40% of the cpu time). With a large number of naive users this is a serious problem. Even `sophisticated' users sometimes accidentally slug a machine for a few days. It would be much friendlier to the community if an SML process running (foreground under a shell) under Xterm or under emacs would die when the user exits from X-windows or suntools. Comment: [JHR] I was unable to reproduce this. Perhaps there setup is such that a SIGHUP isn't getting generated. Status: can't reproduce ---------------------------------------------------------------------- 503. illegal instruction -- core dumps Submitter: Markus Freericks mfx@cs.tu-berlin.de Date: 28.1.92 Version: 0.75 System: Sparc 2 (4/50), 16M, SunOS Severity: Major, at least for me Problem: When running my compiled program, sml encounters an "illegal instruction" and dumps core. When the program is interpreted, there is a message ----------------------------------------------------------------------------- Error: Compiler bug: no default in interp ----------------------------------------------------------------------------- the bug seems to occur in a totally normal case expression. I am currently trying to isolate the error, but would like to know whether there is some special thing to look for. I use an sml image that contains the full Edinburgh library; the code that dumps core is part of the semantic rules of a parser written in sml-yacc. The code is heavy with functionals. Just to get an idea of what the code looks like, the function where the error occurs is ----------------------------------------------------------------------------- fun makeParamDecl(oflag:bool,headId:S.T,(id,arglists:((S.T * Texpr) list list)),body : Texpr)= fn {env=E} => let fun loop ([]:(S.T*Texpr)list list,comb:ACexpr->ACexpr,env) = let val {free=f,used=u,expr=e} = body {env=env} in {defs = [id], expr = {free=f, used=u, expr=comb(e) }} end | loop (args::argss,comb,env) = let (* rename the parameters if necessary *) val params = map #1 args val typtexprs = map #2 args val typacterms= map (fn x => x {env=env}) typtexprs val typcterms = map (fn x => (output(std_out,"mpdloop1\n"); (case x of (Complex(_)) => output(std_out,"complex\n") | (Atomic(_)) => output(std_out,"atomic\n")); output(std_out,"mpdloop2\n"); (case x of Atomic(X) => X | Complex(Y)=> (output(std_out,"error: type var must be atomic:\n"); Cterm.print std_out (Y objVar); objVar)) )) typacterms val renames = renameSyms env params val env' = Env.addList (ListPair.zip(params,renames)) env val env''= putNewEE(putNewState(env)) val k = S.gen("_k") fun comb' x = comb(Atomic(C.Lambda((ListPair.zip(renames,typcterms))@ [(k,objVar), (getEE env'',objVar), (getState env'',objVar)], applyK(x,C.Var(k),env'')))) in loop(argss,comb',env') end in loop(arglists,(fn x=>x),E) end Comment: when called, "mpdloop1" gets printed, then the error message appears. This is independent of the value of "x" (Atomic of Complex). As I said, am trying to reduce the error-generating code to manageable size and send that to you, but that may take a while. Status: fixed in 0.75 ---------------------------------------------------------------------- 504. Another core dump Submitter: Markus Freericks mfx@cs.tu-berlin.de Date: 28.1.92 Version: 0.75 System: Sparc 2 (4/50), 16M, SunOS Severity: Major, at least for me This is a followup to my earlier message. The following code dumps core on my machine, even though it is interpreted! (I hadn't got the nerve to reduce it any further, because startup-time for sml on this system is in the order of 30 seconds) Code: SML_NJ.Control.interp :=true; structure Symbol=Int signature CTERM = sig datatype CONV = Check | Cast datatype T = Var of Symbol.T | Const of String.T | Apply of T list val print : outstream -> T -> unit end structure Cterm : CTERM = struct datatype CONV = Check | Cast datatype T = Var of Symbol.T | Const of String.T | Apply of T list fun indStringList indent = fn Var(x) => [(indent,"var")] | Const(s) => [(indent,"const")] | Apply(args) => (List.foldR' (fn a => fn b => a @ b) (map (fn (expr) => (indStringList (indent+1) expr)) args)) fun print os x = ((indStringList 1 x);()) end structure B = struct structure S = Symbol structure SS = Int structure C = Cterm type Env = bool datatype ACexpr = Atomic of C.T | Complex of C.T -> C.T type TexprResult = {free:SS.T,used:SS.T,expr:ACexpr} type Texpr = {env:Env} -> TexprResult fun mkDummyExpr(x) : Texpr = fn {env=E} => {free = 1 , used = 2 , expr = Atomic(C.Const("\"dummyE:"^x^"\""))} val dummyExpr = mkDummyExpr("") val objVar = C.Var(1) fun makeParamDecl((id,arglists:((S.T * Texpr) list list)),body : Texpr)= fn {env=E} => let fun loop ([],comb:ACexpr->ACexpr,env) = let val {free=f,used=u,expr=e} = body {env=env} in {defs = [id], expr = {free=f, used=u, expr=comb(e) }} end | loop (args::argss,comb,env) = let (* rename the parameters if necessary *) val params = map #1 args (* typcon mismatch if *) (* commented out *) val typtexprs = map (fn (a,b)=>b) args val typacterms= map (fn x => x {env=env}) typtexprs (* typacterms=[Atomic(objVar)] would be ok *) (* [] instead of typtexprs would be ok,too *) val _ = output(std_out,"makeParamDecl-2\n") val typcterms = map (fn x => (output(std_out,"mpdloop1\n"); (*XXXX*) (case x of (Complex _) => output(std_out,"complex\n") | (Atomic _) => output(std_out,"atomic\n")); output(std_out,"mpdloop2\n"); (case x of Atomic(X) => ( (*this here print causes the error!*) Cterm.print std_out X; X) | Complex(Y)=> (output(std_out,"error: type var must be atomic:\n"); Cterm.print std_out (Y objVar); objVar)) )) typacterms val _ = output(std_out,"makeParamDecl-5\n") in loop(argss,comb,env) end in loop(arglists,(fn x=>x),E) end end; val xx = B.makeParamDecl((12, [[(1,B.dummyExpr)]]), B.dummyExpr ); fun killMe() = xx({env=true}) (* calling killMe results in a bus error *) killMe() Comment: The main problem seems to be the type error at (*XXXX*): "typtexprs" is of type "Texpr", so "typacterms" is a "TexprResult", not an "ACterm", as assumed by the "case x of Atomic...". This being undetected, a runtime error follows quite naturally. Funny enough, if the "Apply" clause in "indStringList" is removed by some simple rhs that doesn't inspect the argument of the Apply, no runtime error occurs. PS. After having found the type error, the function runs fine. Guess that makes the Severity "minor, at least for me". Status: fixed in 0.75 ---------------------------------------------------------------------- 505. bad datatype definition accepted Submitter: John Reppy Date: 1/28/92 Version: 0.76 Severity: minor Problem: The following is not legal SML (cf. Definition, sec 2.9), but is accepted by the compiler: Transcript: Standard ML of New Jersey, Version 0.76, December 14, 1991 Arrays have changed; see Release Notes val it = () : unit - datatype foo = FOO of int | BAR and bar = BAR; datatype foo con BAR : foo con FOO : int -> foo datatype bar con BAR : bar Status: fixed in 0.91 (dbm) ---------------------------------------------------------------------- 506. Runbind exception Submitter: Thomas M. Breuel <tmb@ai.mit.edu> Date: 31 Jan 1992 Version: 0.75 System: SparcStation IPC SunOS 4.1.1 Severity: major (?) Problem: code dies with "uncaught exception Runbind" when put into "structure All" Code: local type time = System.Timer.time val timeofday : unit -> time = System.Unsafe.CInterface.c_function "timeofday" in fun timeit f = let open System.Timer val t = start_timer() val rt = timeofday() val z = f () val rt' = sub_time(timeofday(),rt) val t' = check_timer t val ts = check_timer_sys t val tg = check_timer_gc t in print(implode["user: ",makestring t', " gc: ", makestring tg, " system: ",makestring ts, " real: ",makestring rt',"\n"]); z end end; structure All = struct signature RA2 = sig exception Subscript type array val array : (int * int) * real -> array val dim : array * int -> int val sub : array * (int * int) -> real val update : array * (int * int) * real -> unit end; structure X:RA2 = struct structure R = RealArray exception Subscript = R.RealSubscript datatype array = A of (int * int) * R.realarray fun array((d0,d1),initial) = A((d0,d1),R.array(d0*d1,initial)) fun dim(A((d0,d1),_),0) = d0 | dim(A((d0,d1),_),1) = d1 | dim _ = raise Subscript fun sub(A((d0,d1),a),(i,j)) = R.sub(a,i*d1+j) fun update(A((d0,d1),a),(i,j),v) = R.update(a,i*d1+j,v) end; structure Y:RA2 = struct structure R = RealArray structure A = Array exception Subscript = R.RealSubscript (*HACK*) type array = R.realarray A.array fun dim(a,0) = A.length(a) | dim(a,1) = R.length(A.sub(a,0)) | dim _ = raise Subscript fun array((d0,d1),initial) = A.tabulate(d0,fn j => R.array(d1,initial)) fun sub(a,(i,j)) = R.sub(A.sub(a,i),j) fun update(a,(i,j),v) = R.update(A.sub(a,i),j,v) end; functor Test(A2:RA2) = struct fun dotimes(n,f) = let fun loop(i) = if i>=n then () else (f(i); loop(i+1)) in loop(0) end fun foldtimes(n,r,f) = let fun loop(i,r) = if i>=n then r else loop(i+1,f(r,i)) in loop(0,r) end fun a before b = a fun fold(a,r,f) = foldtimes(A2.dim(a,1),r,fn (r,y) => foldtimes(A2.dim(a,0),0.0,fn (r,x) => (f(r,A2.sub(a,(x,y)))) before (A2.update(a,(x,y),r)))) fun bound(x) = if x>=1.0 then bound(x-1.0) else x fun combine(x,y) = bound(x*1.17812+y) fun doit() = let val w = 512 val h = 512 val a = A2.array((w,h),0.0001) in dotimes(2,fn i => fold(a,0.0,combine)) end val _ = timeit(doit) end; end; open All; Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - [opening compare.sml] val timeit = fn : (unit -> 'a) -> 'a compare.sml:25.1-33.7 Warning: signature found inside structure or functor compare.sml:62.1-92.7 Warning: functor found inside structure or functor structure All : sig signature RA2 = sig exception Subscript type array val array : (int * int) * real -> array val dim : array * int -> int val sub : array * (int * int) -> real val update : array * (int * int) * real -> unit end functor Test : <sig> structure X : RA2 structure Y : RA2 end open All [closing compare.sml] val it = () : unit - structure Dummy = Test(X); uncaught exception Runbind - Comments: This seems to be different from the bugs relating to Runbind in the masterbugs list (all of those claim to have been fixed or claim to be unreproducible). Status: fixed in 0.84 ---------------------------------------------------------------------- 507. most negative integer causes compiler bug (see also 630, 632) Submitter: Thomas Yan (tyan@cs.cornell.edu) Date: 2/3/92 Version: 0.75? Severity: minor Problem: Sometimes the compiler has problems with the most negative integer: Transcript: fun f ~0x40000000 = 7; std_in:1.1-1.21 Warning: match not exhaustive ~1073741824 => ... Error: Compiler bug: Overflow in cps/generic.sml - Status: fixed in 0.90 ---------------------------------------------------------------------- 508. xorb Submitter: Thomas Yan (tyan@cs.cornell.edu) Date: 2/3/92 Version: 0.75? Severity: minor Problem: xorb gives wrong answer Transcript: - fun f x = x xorb ~0x40000000; val f = fn : int -> int - f 0; val it = uncaught exception Boxity - fun f x = x xorb ~0x40000000; val f = fn : int -> int - f 0; val it = ~1073741824 : int - Status: fixed in 0.84 ---------------------------------------------------------------------- 509. compiler bug in number pattern Submitter: Thomas Yan (tyan@cs.cornell.edu) Date: 2/3/92 Version: 0.75? Severity: minor Problem: Compiler bug in hexidecimal pattern Transcript: - fun f 0x3fffffff = 2; std_in:3.1-3.20 Warning: match not exhaustive 1073741823 => ... Error: Compiler bug: Overflow in cps/generic.sml Comment: After looking at cps/generic.sml, I think the problem is with generating code with immediate data. Often, things like (INT u) op v get translated into <machine op> (immed (u+u)) v, where the u+u is for the boxity scheme (the +1 comes from v). But when u is already near the limit, then u+u overflows. Obviously, it would be nice for this to get fixed. Status: open (duplicate of 507) ---------------------------------------------------------------------- 510. poor error message in ml-lex (same as 475) Submitter: Reppy Date: 2/1/92 Version: 0.75? Severity: minor? Problem: The following lex file %% special = [@#$%^&*_+=|\\/<>-]; %% <INITIAL>\n => (inc ln; lex()); produces ? sml-lex: uncaught exception LOOKUP Comments: I believe this is because there are special characters in the [...], but this is a poor error message. Status: same as 475 ---------------------------------------------------------------------- 511. dying on interupt with SIGEMT (same as 484, 518) Submitter: tmb@ai.mit.edu (Thomas M. Breuel) Date: January 14, 1992 Version: 0.75 System: SunOS 4.1.?, Sparc IPC Severity: major Problem: When typing Control-C, the system dies with a SIGEMT Code: (this doesn't seem to be specific to any code) Transcript: - trymatches(model,image,BoundedMatch.eval,5.0,10.0,0.4); ((17.0,11.0),(222.0,175.0)) ((5.0,5.00028),(552.0,473.0)) ((~217.0,~169.99972),(535.0,462.0)) ~217.0 ~212.0 SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0xa150) Process Inferior mysml exited abnormally with code 3 Comments: This is also given as bug 304 in the "masterbugs" list, but it is not listed in the "openbugs" list anymore. Did this bug come back or was it never fixed? Based on the PC info, this was probably an OS bug. Changes to the GC invocation mechanism mean that it is moot. -- JHR Status: fixed ---------------------------------------------------------------------- 512. compiler looping Submitter: tmb@ai.mit.edu Date: January 15, 1992 Version: 0.75 (loaded+dumped mylib) System: SunOS 4.1.?, Sparc IPC Severity: major Problem: compiling the red-black tree code below inside the "structure ... = struct ... end" fills up memory and doesn't seem to terminate; compiling at top-level works fine Code: (* Red-Black Trees *) signature ODICT = sig type 'a Dict val lookup : ('a -> 'b) * ('b * 'b -> bool) * 'a Dict * 'b -> 'a val insert : ('a -> 'b) * ('b * 'b -> bool) * 'a Dict * 'a -> 'a Dict val aslist : 'a Dict -> 'a list end; structure RBTree:ODICT = struct datatype Color = Rd | Bl datatype 'a Node = ND of Color * 'a * 'a Node * 'a Node | LEAF; type 'a Dict = 'a Node fun aslist(LEAF) = [] | aslist(ND(c,k,l,r)) = aslist(l) @ k @ aslist(r) exception Lookup fun lookup(key,less,LEAF,k) = raise Lookup | lookup(key,less,ND(_,v,l,r),k) = if less(k,key(v)) then lookup(key,less,l,k) else if less(key(v),k) then lookup(key,less,r,k) else v fun rewrite(ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta))) = (ND(Rd,B,ND(Bl,A,alpha,beta),ND(Bl,C,gamma,delta))) | rewrite(ND(Bl,C,ND(Rd,A,alpha,ND(Rd,B,beta,gamma)),delta)) = ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta)) | rewrite(ND(Bl,C,ND(Rd,B,ND(Rd,A,alpha,beta),gamma),delta)) = ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta)) | rewrite(ND(Bl,A,alpha,ND(Rd,B,ND(Rd,C,beta,gamma),delta))) = ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta)) | rewrite(ND(Bl,A,alpha,ND(Rd,B,beta,ND(Rd,C,gamma,delta)))) = ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta)) | rewrite x = x; fun insert(key,less,v,tree) = let fun insert'(LEAF) = ND(Rd,v,LEAF,LEAF) | insert'(ND(Bl,v',left,right)) = if less(key(v),key(v')) then rewrite(ND(Bl,v',insert'(left),right)) else if less(key(v'),key(v)) then rewrite(ND(Bl,v',left,insert'(right))) else ND(Bl,v',left,right) | insert'(ND(Rd,v',left,right)) = if less(key(v),key(v')) then ND(Rd,v',insert'(left),right) else if less(key(v'),key(v)) then ND(Rd,v',left,insert'(right)) else ND(Rd,v',left,right); val ND(_,v,l,r)=insert'(tree) in ND(Bl,v,l,r) end fun create(key,less,l) = let fun loop([],r) = r | loop(x::xs,r) = loop(xs,insert(key,less,x,r)) in loop(l,LEAF) end; fun id x = x fun lt(x:int,y) = x<y end; Transcript: NJ/SML, mylib val it = () : unit - <--- I've comented out the structure... surrounding the Red-Black tree code [opening redblack.sml] signature ODICT = sig type 'a Dict val lookup : ('b -> 'a) * ('a * 'a -> bool) * 'b Dict * 'a -> 'b val insert : ('b -> 'a) * ('a * 'a -> bool) * 'b Dict * 'b -> 'b Dict val aslist : 'a Dict -> 'a list end datatype Color con Bl : Color con Rd : Color datatype 'a Node con LEAF : 'a Node con ND : Color * 'a * 'a Node * 'a Node -> 'a Node type 'a Dict = 'a Node val aslist = fn : 'a list Node -> 'a list exception Lookup val lookup = fn : ('a -> 'b) * ('b * 'b -> bool) * 'a Node * 'b -> 'a val rewrite = fn : 'a Node -> 'a Node redblack.sml:56.3-56.31 Warning: binding not exhaustive ND (_,v,l,r) = ... val insert = fn : ('a -> 'b) * ('b * 'b -> bool) * 'a * 'a Node -> 'a Node val create = fn : ('a -> 'b) * ('b * 'b -> bool) * 'a list -> 'a Node val id = fn : 'a -> 'a val lt = fn : int * int -> bool [closing redblack.sml] val it = () : unit - <--- I've put the structure ... = struct ... end back [opening redblack.sml] signature ODICT = sig type 'a Dict val lookup : ('b -> 'a) * ('a * 'a -> bool) * 'b Dict * 'a -> 'b val insert : ('b -> 'a) * ('a * 'a -> bool) * 'b Dict * 'b -> 'b Dict val aslist : 'a Dict -> 'a list end [Major collection... [Increasing heap to 3420k] [Increasing heap to 3560k] [Increasing heap to 4260k] [Increasing heap to 7760k] 69% used (1952632/2809440), 2100 msec] [Increasing heap to 8192k] [Major collection... 94% used (3980248/4209932), 4600 msec] [Increasing heap to 12344k] [Major collection... [Increasing heap to 18924k] 94% used (6180760/6516556), 7060 msec] [Increasing heap to 19104k] [Major collection... [Increasing heap to 29280k] Process Inferior sml killed <--- kill -9 <pid> Comments: BTW, do you have code to delete from persistent red-black trees? It gets really messy... Status: fixed in 0.84 ---------------------------------------------------------------------- 513. not waiting for execute children Submitter: Robert S. Thau (rst@ai.mit.edu) Date: 1/20/92 Version: ? Severity: major Problem: SML/NJ appears not to wait for children forked off by execute. This can be a problem in certain circumstances. In my particular case, I wrote a routine which draws graphs for the user by forking off an xplot and sending down plot commands. After fifty graphs or so, the zombie xplots had completely filled my per-user process limit, making it difficult to determine the nature of the problem (ps: cannot fork: no more processes). In this particular case, I'd be more than willing to do the wait myself, but execute gives me no process-id to wait for, just the input and output streams. [from Phil Jeffcock <P.J.Jeffcock@bradford.ac.uk>, 3/2/92] I'm running SML/NJ 0.75 on my SUN Sparc IPC. I've been writing an application which I need to use execute frequently and in doing so the ML runtime is creating a zombie process each time I use it. After a short while I run out of process slots. Any ideas? Fix: just before doing the execute, do wait3(&status,WNOHANG,NULL) to clean up previous children, if any. Status: fixed in 0.91 ---------------------------------------------------------------------- 514. uncaught exception ErrorStructure Submitter: John Reppy Date: 1/15/92 Version: 0.76 Severity: minor Problem: I got the following uncaught exception when working on my Amber stuff: ... [opening join.sml] join.sml:6.25-6.38 Error: unbound functor: AmberLrValsFun [closing join.sml] [closing load] uncaught exception ErrorStructure - I tried a few small examples, but I wasn't able to reproduce the bug. The offending file ("join.sml") is: structure AmberLrVals = AmberLrValsFun (structure Token = LrParser.Token) structure AmberLex = AmberLexFun (structure Tokens = AmberLrVals.Tokens) structure AmberParser = Join ( structure ParserData = AmberLrVals.ParserData structure Lex = AmberLex structure LrParser = LrParser) If I add a ";" to the first line, then I just get the error message. [from Jon Thackray <jont@harlqn.co.uk>, 4/8/92]: Ok, here's a stripped down version of the ErrorStructure problem. I don't believe it can get any smaller. The significant factors seems to be twofold, firstly, the missing parameter to the Mir_Utils functor, and secondly the sharing constraint between the parameters of this functor. The first factor in isolation is not sufficient to produce the problem, as far as I can tell. Hope this helps. signature MIRTYPES = sig end; signature MIRPRINT = sig structure MirTypes : MIRTYPES end; functor Mir_Utils( structure MirTypes : MIRTYPES structure MirPrint : MIRPRINT sharing MirTypes = MirPrint.MirTypes ) = struct end; structure MirTypes_ = struct end; structure Mir_Utils_ = Mir_Utils( structure MirTypes = MirTypes_ ); Status: fixed in 0.84 ---------------------------------------------------------------------- 515. Compiler bug: patType -- unexpected pattern Submitter: jont@uk.co.harlqn Date: 24/01/92 Version: SML of NJ version 0.75 System: Sun 4/330 with Sunos 4.1.1 Severity: minor Problem: Compiler bug Code: | has_a_new_name (TYFUN (CONSTYPE (_,METATYNAME{ref tyfun, ...}),_)) = Transcript: /usr/users/jont/ml/ml_compiler/src/typechecker/_types.sml:383.57-383.61 Error: syntax error: inserting AS /usr/users/jont/ml/ml_compiler/src/typechecker/_types.sml:1177.38 Error: syntax error: inserting ASTERISK Error: Compiler bug: patType -- unexpected pattern [closing /usr/users/jont/ml/ml_compiler/src/typechecker/_types.sml] Comments: same as #474? Status: probably fixed in 0.83 ---------------------------------------------------------------------- 516. ml-lex gives uncaught exception LOOKUP (same as 475, 510) Submitter: John Reppy Date: 2/4/92 Version: ? Severity: significant Problem: One of my students was getting the following mysterious error message from mllex: ? sml-lex: uncaught exception LOOKUP upon examination, the problem is that he misspelled a character class name. The following small file will produce this behavior: Code: <jhr@bat> cat foo.lex (* test file *) %% foo = [a-z]; %% <INITIAL>{foob}+ => (lex()); Status: same as 475 ---------------------------------------------------------------------- 517. type errors in examples/cat.sml Submitter: Doug McIlroy Date: 2/4/92 Version: ? Severity: minor Problem: doc/examples/cat.sml contains type errors Status: fixed for 0.90 (in /usr/local/sml/75/doc/examples/cat.sml) ---------------------------------------------------------------------- 518. interrupt causes core dump (same as 484, 511) Submitter: jont@uk.co.harlqn Date: 12/02/92 Version: SML of NJ version number 0.75 System: Sun 4/330 with SunOS 4.1.1 Severity: minor Problem: Unreliability of NJ 0.75 with ^c Transcript: SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0xa150) Comments: This seems to happen a lot when using ctrl-c to halt a looping or long running program. Even if this doesn't happen, the image sometimes seems corrupt afterwards, in that it exhibits strange (impossible) behaviour that doesn't occur if it is recompiled from scratch to supposedly the same state. I suspect there is a critcial region problem somewhere. Status: open ---------------------------------------------------------------------- 519. System.system broken after loading sml-yacc output Submitter: John Nestoriak <nestorak@cs.psu.edu> Date: 2/16/92 Version: 0.75 Severity: major Problem: I'm having a problem using system calls from sml 75. Something like System.system "ls"; works fine until I load the output from sml-yacc. Then I get uncaught exception SystemCall. [from cazin@tls-cs.cert.fr (Jacques Cazin), 3/26/92] But we use also lexgen and mlyacc which are in the distribution. After having loaded lexgen, we cannot use "System.system" anymore: System.system "pwd"; (or anything else) gives rise to uncaught exception SystemCall We previously used version 0.56 with lexgen as well and did not observe this behaviour. Status: fixed in 0.86 ---------------------------------------------------------------------- 520. broken under IRIX 4.0.1 Submitter: Lindsay Errington <lindsay@cs.mu.OZ.AU> Date: 2/17/92 Version: 0.75 System: SGI/IRIX 4.0.1 Severity: major Problem: I'm sorry to bother you with such a vague problem but I'm having a little trouble with your compiler under IRIX. We've just upgraded from Irix 3.3.x to version 4.0.1 and since then any attempt to use the "use" function made SML 0.75 hang. I tried to re-compile the runtime but then it only gets as far as [Executing IEEEReal] before it hangs again. I've done a little diddling and as far as I can tell it's hung in prim.s. Any suggestions on where to start looking or whom to contact? Status: Fixed in 0.81 ---------------------------------------------------------------------- 521. type checking flex records Submitter: Mark Leone (mleone@cs.cmu.edu) Date: 2/12/92 Version: 0.75 System: Decstation 2100 under Mach 2.6 Severity: major Problem: Type checker doesn't handle flex records correctly. Code: fun foo x = let val a = #1 x val (a,b) = x in b () end Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - fun foo x = let val a = #1 x val (a,b) = x in b () end ; = = = = = val foo = fn : 'a * 'b -> 'c - foo (0,0); Process sml segmentation fault Comments: Type of foo should be ('a * (unit -> 'b)) -> 'b Status: fixed in 0.85 ---------------------------------------------------------------------- 522. redundent patterms in compiler Submitter: John Reppy Date: 2/18/92 Version: 0.76? Severity: minor Transcript: build/index.sml:177.4 Warning: redundant patterns in match VALdec vbs => ... VALRECdec rvbs => ... TYPEdec tbs => ... DATATYPEdec {datatycs=datatycs,withtycs=withtycs} => ... ABSTYPEdec {abstycs=abstycs,body=body,withtycs=withtycs} => ... EXCEPTIONdec ebs => ... STRdec sbs => ... ABSdec sbs => ... FCTdec fbs => ... SIGdec sigvars => ... LOCALdec (inner,outer) => ... SEQdec decs => ... OPENdec strVars => ... MARKdec (dec,L1,L2) => ... FIXdec _ => ... OVLDdec _ => ... IMPORTdec _ => ... --> _ => ... translate/translate.sml:259.30 Warning: redundant patterns in match VALtrans (PATH p) => ... VALtrans (INLINE POLYEQL) => ... VALtrans (INLINE POLYNEQ) => ... VALtrans (INLINE INLSUBSCRIPT) => ... VALtrans (INLINE INLUPDATE) => ... VALtrans (INLINE INLBYTEOF) => ... VALtrans (INLINE INLSTORE) => ... VALtrans (INLINE INLORDOF) => ... VALtrans (INLINE INLFSUBSCRIPTd) => ... VALtrans (INLINE INLFUPDATEd) => ... VALtrans (INLINE i) => ... THINtrans (PATH p,v,locs) => ... CONtrans (d as DATACON {const=true,...}) => ... CONtrans (d as DATACON {const=false,...}) => ... VALtrans a => ... THINtrans (a,_,_) => ... --> _ => ... cps/cpsopt.sml:1129.4 Warning: redundant patterns in match RECORD (vl,w,e) => ... SELECT (i,v,w,e) => ... OFFSET (i,v,w,e) => ... APP (f,vl) => ... FIX (l,e) => ... SWITCH (v,_,el) => ... BRANCH (_,vl,c,e1,e2) => ... LOOKER (_,vl,w,e) => ... SETTER (_,vl,e) => ... PURE (_,vl,w,e) => ... ARITH (args as (floor,_,_,_)) => ... ARITH (args as (round,_,_,_)) => ... ARITH (args as (fadd,_,_,_)) => ... ARITH (args as (fdiv,_,_,_)) => ... ARITH (args as (fmul,_,_,_)) => ... ARITH (args as (fsub,_,_,_)) => ... ARITH (_,vl,w,e) => ... --> PURE (args as (fnegd,v :: nil,w,e)) => ... --> PURE (real,vl,w,e) => ... Status: Fixed in 0.81 ---------------------------------------------------------------------- 523. printing uncaught exceptions Submitter: Richard O'Neill <richard@smaug.questor.wimsey.bc.ca> Date: Thu Feb 27 14:32:47 PST 1992 Version: 0.75 System: NeXTstation, OS2.1 Severity: Major annoyance Problem: If a value happens to be of type exn, the top level loop won't print out the value, but instead says 'val it = exn : exn'; this is not acceptable behaviour in my opinion. When debugging, I like to be able to pass back information when an fatal exception is raised. It is bad enough that if you have: exception InvalidKey of int; ... raise InvalidKey 6502; it gives the message uncaught exception InvalidKey and not: uncaught exception: InvalidKey 6502 (But the 'Io' exception does 'do the right thing'- special case treatment or what :o) But I can put up with that - what really annoys me is that even the top level won't print exception values, i.e. - val theException = InvalidKey 6502; val theException = exn : exn In order to find the value, I need to do: - case theException of InvalidKey key => key; std_in:3.1-3.42 Warning: match not exhaustive InvalidKey key => ... val it = 6502 : int This is annoying, because it means more work for me to do, especially if the datastructure is a *chain* of exception values (e.g. something like 'exception ReraiseBacktrace of functionName * parameters * exn' - you get the idea anyway). In such a case, I have to follow the chain *by hand*. I realise that printing exeptions may be harder than printing ordinary constructors, but don't think this is a good reason not to print them. [Richard O'Neill, 11/24/92] Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - val some_exceptions = [Interrupt, Match, Bind, Io "Foobar"]; val some_exceptions = [exn,exn,exn,exn] : exn list - ^D If a value happens to be of the exception type, it is always printed in a most uninformative way. Obviously, I'd like to see: Standard ML of New Jersey, Version 0.93, February 17, 1993 ;-) val it = () : unit - val some_exceptions = [Interrupt, Match, Bind, Io "Foobar"]; val some_exceptions = [Interrupt, Match, Bind, Io "Foobar"] : exn list - ^D Thus bug already has a number, 523, but the title "printing uncaught exceptions" is misleading, and I expect probably the reason it hasn't been fixed (yet). (Better printing of uncaught exceptions would be nice too, but that is far less important to me). Unless I'm seriously mistaken, this bug would only take minutes to fix, for someone who knows SML-NJ's data-structures. Comment: (awa) Fixed a little bit; exn values now print a top level, but not the value carried by the constructor. Status: not entirely a bug ---------------------------------------------------------------------- 524. weak polymorphism Submitter: shail@au-bon-pain.lcs.mit.edu (Shail Aditya) Date: 12/19/91 Version: ? Severity: major Problem: I ran across this quirk in the ranked weak type inference in SML-NJ. I am running the version 0.75 on Sparc (sunos). - val g3 = (fn f => (fn x => f x)); val g3 = fn : ('a -> 'b) -> 'a -> 'b - g3 ref; std_in:5.1-5.6 Error: nongeneric weak type variable it : '0Z -> '0Z ref - The "ref" does not happen until another argument is supplied to "g3 ref", so proper ranking analysis should have made its type to be "'1a -> '1a ref" without any error. - val g = (fn x => x); val g = fn : 'a -> 'a - g ref; std_in:3.1-3.5 Error: nongeneric weak type variable it : '0Z -> '0Z ref But the following works. - val h = (fn x => let val g = fn x => x in g ref end); val h = fn : 'a -> '1b -> '1b ref - val h = (fn x => let val g = (fn f => (fn x => f x)) in g ref end); val h = fn : 'a -> '1b -> '1b ref - Basically, it seems that "ref" is opened up to the enclosing lambda rank unnecessarily when it is passed as an argument. This system works fine in first order situations but fails in higher order argument passing when the arguments are weakly polymorphic functions. Am I to understand that the ranked system of SML-NJ is not powerful enough to keep track of weak polymorphism across higher order function applications? Or is this merely a bug? I would like to obtain a clearer description of the ranked system you follow. Preferably in terms of a paper that gives the inference rules. I have a system that behaves similarly, only that it allows toplevel non-ground weak types as well. I would like to know the SML-NJ solution better. Do you have any pointers? Status: not a bug (a "feature" of weak polymorphism) ---------------------------------------------------------------------- 525. IO.execute broken Submitter: Mikael Pettersson, mpe@ida.liu.se Date: Jan 7, 1992 Version: 0.75 System: SPARCstation ELC, SunOS 4.1.1 Severity: major Problem: the input stream from IO.execute is unusable: can_input and close_in fail with exceptions, input causes a segmentation violation Transcript: ==== - val (is,_) = execute("/bin/echo",["foo"]); val is = - : instream - close_in is; uncaught exception Io "close_in "<pipe_in>": close failed, Bad file number" ==== - val (is,_) = execute("/bin/echo",["foo"]); val is = - : instream - input(is,1); Segmentation fault (core dumped) ==== - val (is,_) = execute("/bin/echo",["foo"]); val is = - : instream - can_input is; uncaught exception SystemCall - (can_input is) handle (System.Unsafe.CInterface.SystemCall s) => (print s; print "\n"; 999); fionread failed, Bad file number val it = 999 : int Status: fixed in 0.84 ---------------------------------------------------------------------- 526. Harlequin gripes Submitter: Andrew Tolmach Date: 3/2/92 Version: 0.75 Severity: minor Problem: 1) If one uses polymorphic equality on, say, integer types, the equality test is much slower than using a type-specific equality operator. This was probably in the context of functors, in which case its no big surprise, but might bear looking into further. 2) They were unhappy with the time cost of referencing elements out of structures at runtime. They often do something like inserting an explicit declaration val thing = A.thing same thing for them automatically. They also suggested that we don't tend to notice this problem because we use "open" all over the place, a practice they abominate. Status: not a bug ---------------------------------------------------------------------- 527. uncaught exception Subscript while printing value of a datatype Submitter: John Reppy Date: 3/9/92 Version: 0.78 Severity: major Problem: compiling following code causes uncaught exception Subscript Code: (* string-util.sml * * Various string utilities. *) structure StringUtil = struct datatype relation_t = Equal | LessTh | GreaterTh (* lexically compare two strings and return their relation *) fun strcmp (s1, s2) = (case (size s1, size s2) of (0, 0) => Equal | (0, _) => LessTh | (_, 0) => GreaterTh | (n1, n2) => let fun loop i = let val c1 = ordof(s1, i) and c2 = ordof(s2, i) in if (c1 = c2) then loop(i+1) else if (c1 < c2) then LessTh else GreaterTh end in (loop 0) handle _ => ( if (n1 = n2) then Equal else if (n1 < n2) then LessTh else GreaterTh) end (* strcmp *) (* end case *)) (* Lexically sort a list of values with unique string keys. The function * proj extracts the key of an item. Raise Repeat if two items have the * same key. *) exception Repeat of string fun sortStrings proj = let fun le (f1, f2) = (case strcmp(proj f1, proj f2) of LessTh => true | GreaterTh => false | Equal => raise Repeat(proj f1) (* end case *)) fun insert (f, []) = [f] | insert (f, l as (f'::r)) = if le(f, f') then f::l else f'::insert(f, r) fun sort ([], l) = l | sort (f::r, l) = sort(r, insert(f, l)) in fn l => sort (l, []) end end (* StringUtil *) (* this is a SML implementation of Luca's Amber code *) (* Types are represented by values in the following type. Rec bound variables * in a recursive type are represented by the RecTy node in which they are bound. * For example, the representation of the following Amber type * * rec (t) [nil : Unit, cons : {hd : Int, tl : t}] * * is constructed by the following ML code: * * let * val recBody = ref Any * val recTy = RecTy{bind = "t", typ = recBody} * val body = VariantTy[ * FieldTy{tag = "nil", typ = BaseTy UnitTy}, * FieldTy{tag = "cons", typ = RecordTy[ * FieldTy{tag = "hd", typ = BaseTy IntTy}, * FieldTy{tag = "tl", typ = recTy}, * ] * ] * in * recBody := body; * recTy * end *) datatype base_ty = UnitTy | BoolTy | IntTy | StringTy | DynamicTy datatype typ = AnyTy (* | ExistTy of {name : string, instance : typ option, suptypes : typ list}*) | BaseTy of base_ty | FunTy of (typ * typ) | TupleTy of typ list | RecordTy of field_ty list (* assume fields are sorted by tag *) | VariantTy of field_ty list | RecTy of {bind : string, typ : typ ref} | ArrayTy of typ | ChannelTy of typ and field_ty = FieldTy of {tag : string, typ : typ} fun seen (stk, ty1 : typ, ty2 : typ) = let val x = (ty1, ty2) fun look [] = false | look (y::r) = (x = y) orelse look r in look stk end (* return true if the types are "equal" *) fun sameType (ty1, ty2) = let fun sameTy (AnyTy, _, _) = true | sameTy (_, AnyTy, _) = true | sameTy (BaseTy b1, BaseTy b2, _) = (b1 = b2) | sameTy (FunTy(t1, s1), FunTy(t2, s2), stk) = sameTy(t1, t2, stk) andalso sameTy(s1, s2, stk) | sameTy (TupleTy tl1, TupleTy tl2, stk) = let fun sameTyList ([], []) = true | sameTyList (ty1::r1, ty2::r2) = sameTy(ty1, ty2, stk) andalso sameTyList(r1, r2) in sameTyList(tl1, tl2) end | sameTy (RecordTy fl1, RecordTy fl2, stk) = sameFieldList (fl1, fl2, stk) | sameTy (VariantTy fl1, VariantTy fl2, stk) = sameFieldList (fl1, fl2, stk) | sameTy (ty1 as RecTy{typ=ty1', ...}, ty2 as RecTy{typ=ty2', ...}, stk) = (ty1' = ty2') orelse seen(stk, ty1, ty2) orelse sameTy(!ty1', !ty2', (ty1, ty2)::stk) | sameTy (ty1 as RecTy{typ, ...}, ty2, stk) = seen(stk, ty1, ty2) orelse sameTy(!typ, ty2, (ty1, ty2)::stk) | sameTy (ty1, ty2 as RecTy{typ, ...}, stk) = seen(stk, ty1, ty2) orelse sameTy(ty1, !typ, (ty1, ty2)::stk) | sameTy (ArrayTy ty1, ArrayTy ty2, stk) = sameTy(ty1, ty2, stk) | sameTy (ChannelTy ty1, ChannelTy ty2, stk) = sameTy(ty1, ty2, stk) | sameTy _ = false and sameFieldList ([], [], _) = true | sameFieldList (FieldTy{tag=a, typ=t}::r1, FieldTy{tag=b, typ=s}::r2, stk) = (a = b) andalso sameTy(t, s, stk) andalso sameFieldList(r1, r2, stk) | sameFieldList _ = false in sameTy (ty1, ty2, []) end (* return true, if ty1 is a subtype of ty2 *) fun isSubtyOf (ty1, ty2) = let exception TypeError (* given two sorted lists of field types, where the second should contain all of * tags of the first list, return the projection of those fields from the second * list. *) fun projFieldList (fl1, fl2) = let fun proj ([], _, l) = rev l | proj (_, [], _) = raise TypeError | proj ( l1 as (FieldTy{tag=a, ...}::r1), l2 as ((f as FieldTy{tag=b, ...})::r2), l ) = ( print(implode["proj: a = ", a, ", b = ", b, "\n"]); case (StringUtil.strcmp(a, b)) of StringUtil.Equal => proj (r1, r2, f::l) | StringUtil.GreaterTh => proj (l1, r2, l) | StringUtil.LessTh => proj (r1, l2, l) (* end case *)) in proj (fl1, fl2, []) end fun subTy (AnyTy, _, _) = true | subTy (_, AnyTy, _) = true | subTy (BaseTy b1, BaseTy b2, _) = (b1 = b2) | subTy (ty1 as RecTy{typ=ty1', ...}, ty2 as RecTy{typ=ty2', ...}, stk) = (ty1' = ty2') orelse seen(stk, ty1, ty2) orelse subTy(!ty1', !ty2', (ty1, ty2)::stk) | subTy (ty1 as RecTy{bind, typ}, ty2, stk) = seen(stk, ty1, ty2) orelse subTy(!typ, ty2, (ty1, ty2)::stk) | subTy (ty1, ty2 as RecTy{bind, typ}, stk) = seen(stk, ty1, ty2) orelse subTy(ty1, !typ, (ty1, ty2)::stk) | subTy (FunTy(ty1, ty2), FunTy(ty1', ty2'), stk) = subTy(ty1', ty1, stk) andalso subTy(ty2, ty2', stk) | subTy (TupleTy tl1, TupleTy tl2, stk) = let fun subTyList ([], []) = true | subTyList (t1::r1, t2::r2) = subTy(t1, t2, stk) andalso subTyList(r1, r2) | subTyList _ = false in subTyList(tl1, tl2) end | subTy (RecordTy f1, RecordTy f2, stk) = let val f1' = projFieldList (f2, f1) in subFieldList (f1', f2, stk) end | subTy (VariantTy f1, VariantTy f2, stk) = let val f2' = projFieldList (f1, f2) in subFieldList (f1, f2', stk) end | subTy (ArrayTy ty1, ArrayTy ty2, _) = sameType(ty1, ty2) | subTy (ChannelTy ty1, ChannelTy ty2, _) = sameType(ty1, ty2) | subTy _ = false (* this should only be called on field lists that have the same tags *) and subFieldList ([], [], _) = true | subFieldList (FieldTy{typ=t, ...}::r1, FieldTy{typ=s, ...}::r2, stk) = subTy(t, s, stk) andalso subFieldList(r1, r2, stk) in (subTy (ty1, ty2, [])) handle TypeError => false end fun revApp ([], l) = l | revApp (x::r, l) = revApp(r, x::l) (* Return the union of two field lists, with f mapped over their intersection. *) fun unionFieldMap f = let fun union ([], [], l) = revApp (l, []) | union ([], l2, l) = revApp (l, l2) | union (l1, [], l) = revApp (l, l1) | union ( l1 as ((f1 as FieldTy{tag=a, typ=t1})::r1), l2 as ((f2 as FieldTy{tag=b, typ=t2})::r2), l ) = (case (StringUtil.strcmp(a, b)) of StringUtil.Equal => union (r1, r2, FieldTy{tag = a, typ = f(t1, t2)}::l) | StringUtil.GreaterTh => union (l1, r2, f2::l) | StringUtil.LessTh => union (r1, l2, f1::l) (* end case *)) in fn (fl1, fl2) => union (fl1, fl2, []) end (* Map f over the intersection of two field lists *) fun interFieldMap f = let fun inter ([], _, l) = revApp (l, []) | inter (_, [], l) = revApp (l, []) | inter ( l1 as (FieldTy{tag=a, typ=t1}::r1), l2 as (FieldTy{tag=b, typ=t2}::r2), l ) = (case (StringUtil.strcmp(a, b)) of StringUtil.Equal => inter (r1, r2, FieldTy{tag = a, typ = f(t1, t2)}::l) | StringUtil.GreaterTh => inter (r1, l2, l) | StringUtil.LessTh => inter (l1, r2, l) (* end case *)) in fn (fl1, fl2) => inter (fl1, fl2, []) end exception Join fun joinTy (AnyTy, _) = AnyTy | joinTy (_, AnyTy) = AnyTy | joinTy (ty as BaseTy b1, BaseTy b2) = if (b1 = b2) then ty else raise Join | joinTy (TupleTy tl1, TupleTy tl2) = let fun joinTyList ([], []) = [] | joinTyList ([], _) = raise Join | joinTyList (_, []) = raise Join | joinTyList (ty1::r1, ty2::r2) = joinTy(ty1, ty2) :: joinTyList(r1, r2) in TupleTy(joinTyList (tl1, tl2)) end | joinTy (FunTy(ty1, ty2), FunTy(ty1', ty2')) = FunTy(meetTy (ty1, ty1'), joinTy (ty2, ty2')) | joinTy (RecordTy fl1, RecordTy fl2) = RecordTy (interFieldMap joinTy (fl1, fl2)) | joinTy (VariantTy fl1, VariantTy fl2) = VariantTy (unionFieldMap joinTy (fl1, fl2)) and meetTy (AnyTy, _) = AnyTy | meetTy (_, AnyTy) = AnyTy | meetTy (ty as BaseTy b1, BaseTy b2) = if (b1 = b2) then ty else raise Join | meetTy (TupleTy tl1, TupleTy tl2) = let fun meetTyList ([], []) = [] | meetTyList ([], _) = raise Join | meetTyList (_, []) = raise Join | meetTyList (ty1::r1, ty2::r2) = meetTy(ty1, ty2) :: meetTyList(r1, r2) in TupleTy(meetTyList (tl1, tl2)) end | meetTy (FunTy(ty1, ty2), FunTy(ty1', ty2')) = FunTy(joinTy (ty1, ty1'), meetTy (ty2, ty2')) | meetTy (RecordTy fl1, RecordTy fl2) = RecordTy (unionFieldMap meetTy (fl1, fl2)) | meetTy (VariantTy fl1, VariantTy fl2) = VariantTy (interFieldMap meetTy (fl1, fl2)) (**** Test code ***) fun mkRecTy (id, mkTy) = let val recBody = ref AnyTy val recTy = RecTy{bind = id, typ = recBody} in recBody := mkTy(recTy); recTy end fun mkVar1 (tag, ty) = VariantTy[FieldTy{tag = tag, typ = ty}] val unitTy = BaseTy UnitTy val intTy = BaseTy IntTy (* rec (t) [nil : Unit, cons : {hd : Int, tl : t}] *) val intListTy = mkRecTy("t", fn recTy => VariantTy[ FieldTy{tag = "nil", typ = unitTy}, FieldTy{tag = "cons", typ = RecordTy[ FieldTy{tag = "hd", typ = intTy}, FieldTy{tag = "tl", typ = recTy} ]} ]) (* [cons : {hd : Int, tl : [nil : Unit]}] *) val intListTy' = VariantTy[ FieldTy{tag = "cons", typ = RecordTy[ FieldTy{tag = "hd", typ = intTy}, FieldTy{tag = "tl", typ = VariantTy[ FieldTy{tag = "nil", typ = unitTy} ]} ]} ] ==== The following shorter example causes an uncaught subscript in 0.77 & 0.78 (but not in 0.77b): datatype tree = Leaf of int | Plus of (tree * tree * int); (Plus (Leaf 0,Leaf 1,2),2); for example: Standard ML of New Jersey, Version 0.78, February 26, 1992 Arrays have changed; see Release Notes val it = () : unit - datatype tree = Leaf of int | Plus of (tree * tree * int); datatype tree con Leaf : int -> tree con Plus : tree * tree * int -> tree - (Plus (Leaf 0,Leaf 1,2),2); val it = (Plus ( uncaught exception Subscript - Comment: Bug appeared between 0.77b and 0.77. Possibly related to change in dataconstructor representations. Submitter: Andrzej Filinski <andrzej@cs.cmu.edu> Date: March 19, 1992 Version: 0.78 System: All Severity: Major Problem: Printing certain datatype values raises Subscript Transcript: Standard ML of New Jersey, Version 0.78, February 26, 1992 Arrays have changed; see Release Notes val it = () : unit - datatype foo = BAR of int | BAZ of foo * foo; datatype foo con BAR : int -> foo con BAZ : foo * foo -> foo - BAZ (BAR 1, BAR 2); val it = BAZ ( uncaught exception Subscript - [Bob Harper, 4/10/92]: Dave Tarditi suggested that the constructor printing problem might be due to the fact that something or other got reversed in the code generator, but this was forgotten in the print routines. Apparently some representation is now done in reverse order. I consistently get the following behavior: 1. Build a system using SourceGroup.make. 2. Open a particular structure, making available a constructor Abs (among many others). 3. Modify things, do another make. 4. Uses of Abs suddenly get weird type errors. Typing Abs at top level results in "val it = exn : exn". I could send the whole system, but this seems excessive.... Status: fixed in 0.84 ---------------------------------------------------------------------- 528. Compiler bug: ModuleUtil.teststr 2 Submitter: Ian Green, aisb@ed.ac.uk Date: 18-Mar-92 Version: 0.75 System: Sun SPARC 1+, SunOS 4.1 Severity: john major Problem: Error: Compiler bug: ModuleUtil.teststr 2 Code: ************ UnifyFUN.sml ************* import "TermsSIG"; import "UnifySIG"; functor Unifier(structure Terms:TERMS):UNIFY = struct local open Terms fun unifyst _ _ _ = [] in fun mgu t1 t2 = unifyst [] [(t1,t2)] [] handle No_Unifier => [] end end **************************************** ************ UnifySIG.sml ************** import "TermsSIG"; signature UNIFY = sig local structure Terms:TERMS open Terms in val mgu : Terms.term -> Terms.term -> (Terms.atom * Terms.term) list end end ***************************************** ********** TermsSIG.sml *************** signature TERMS = sig datatype atom = Var of string | Const of string datatype term = Atomic of atom | Term of atom * term list | WhereTerm of atom list * term * term; val subst : atom list -> (atom * term) list -> term -> term end; **************************************** ************ TermsFUN.sml ************* import "TermsSIG"; functor Terms( ):TERMS = struct datatype atom = Var of string | Const of string datatype term = Atomic of atom | Term of atom * term list | WhereTerm of atom list * term * term; fun subst _ _ t = t (* i like this case *) end; **************************************** ************ load ****************** import "TermsFUN"; import "UnifyFUN"; structure Term = Terms( ); structure Unify = Unifier(structure Terms = Term); **************************************** Transcript: In summary, I do three `use "load"' starting with no bin files. The first gives no error, but i get <erro> types (what does that mean). Second time a recompile is needed (odd?) and get a Compiler bug: On the third try, no recompile needed, but get same compiler bug report. Here it is in all its (gory) detail. --------------------------------------------------------- Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "load"; [opening load] [reading TermsFUN.sml] [reading TermsSIG.sml] [writing TermsSIG.bin... done] [closing TermsSIG.sml] [writing TermsFUN.bin... done] [closing TermsFUN.sml] functor Terms signature TERMS [reading UnifyFUN.sml] [reading TermsSIG.bin... done] [reading UnifySIG.sml] [reading TermsSIG.bin... done] UnifySIG.sml:6.6-8.1 Warning: LOCAL specs are only partially implemented [writing UnifySIG.bin... done] [closing UnifySIG.sml] [writing UnifyFUN.bin... done] [closing UnifyFUN.sml] functor Unifier signature UNIFY signature TERMS structure Term : sig datatype atom con Const : string -> atom con Var : string -> atom datatype term con Atomic : atom -> term con Term : atom * term list -> term con WhereTerm : atom list * term * term -> term val subst : atom list -> (atom * term) list -> term -> term end structure Unify : UNIFY [closing load] val it = () : unit - Unify.mgu; val it = fn : <error> -> <error> -> (<error> * <error>) list - use "load"; [opening load] [reading TermsFUN.bin... ] [import(s) of TermsFUN are out of date; recompiling] [closing TermsFUN.bin] [reading TermsFUN.sml] [reading TermsSIG.bin... done] [writing TermsFUN.bin... done] [closing TermsFUN.sml] functor Terms signature TERMS [reading UnifyFUN.bin... done] functor Unifier signature UNIFY signature TERMS structure Term : sig datatype atom con Const : string -> atom con Var : string -> atom datatype term con Atomic : atom -> term con Term : atom * term list -> term con WhereTerm : atom list * term * term -> term val subst : atom list -> (atom * term) list -> term -> term end Error: Compiler bug: ModuleUtil.teststr 2 [closing load] - use "load"; [opening load] [reading TermsFUN.bin... done] functor Terms signature TERMS [reading UnifyFUN.bin... done] functor Unifier signature UNIFY signature TERMS structure Term : sig datatype atom con Const : string -> atom con Var : string -> atom datatype term con Atomic : atom -> term con Term : atom * term list -> term con WhereTerm : atom list * term * term -> term val subst : atom list -> (atom * term) list -> term -> term end Error: Compiler bug: ModuleUtil.teststr 2 [closing load] - Comments: I see from the compiler that LOCAL specs are only partially implemented, so this is probably the cause, though i dont get the <error> bit. As I am new to modules in ML, its all probably meaningless code anyway, but I thought I ought to drop you a line. Status: cannot reproduce (bug report incomplete); probably fixed. ---------------------------------------------------------------------- 529. memory leak Submitter: schristensen@daimi.aau.dk (Soren Christensen) Date: 3/20/92 Version: 0.75 Severity: major Problem: I have a problem that my system slows down after running a short while. Instead of using the ordinary top-loop of the compiler I run my own. This means that I evaluate ML code in the following way: use_stream (open_string "code"); It seems that this construct creates 16 bytes of "garbage" which is never collected. My first idea was that I needed to close the stream which is created, i.e., let val is = open_string "code" in use_stream is; close_in is end; But this does not fix the problem. It seems that "close_in is" have no effect. At least it reports no errors when a use_string is performed on a stream which has been closed. Status: fixed in 0.84 ---------------------------------------------------------------------- 530. missing space in printing abstype declaration Submitter: Mikael Pettersson, mpe@ida.liu.se Date: March 20 1992 Version: 0.75 System: all Severity: minor Problem: when printing a polymorphic abstype, no space is inserted between the "type" symbol and the type variable Transcript: - abstype 'a foo = FOO of 'a list = with = fun mkfoo() = FOO [] = end; type'a foo (* note: missing space after "type" *) val mkfoo = fn : unit -> 'a foo Fix: --cut here-- *** src/print/printdec.sml.~1~ Fri Oct 18 23:21:13 1991 --- src/print/printdec.sml Fri Mar 20 14:00:07 1992 *************** *** 50,56 **** printSym name; print " = "; printType env def; newline()) and printAbsTyc(GENtyc{path=name::_, arity, eq, kind=ref(ABStyc _), ...}) = ! (print(if (!eq=YES) then "eqtype" else "type"); printFormals arity; print " "; printSym name; newline()) --- 50,56 ---- printSym name; print " = "; printType env def; newline()) and printAbsTyc(GENtyc{path=name::_, arity, eq, kind=ref(ABStyc _), ...}) = ! (print(if (!eq=YES) then "eqtype " else "type "); printFormals arity; print " "; printSym name; newline()) --cut here-- Status: fixed in 0.86 ---------------------------------------------------------------------- 531. Compiler bug: CoreLang.makeOVERLOADdec.option Submitter: John Reppy Date: 3/24/92 Version: 0.78 Severity: major Problem: I noticed a "CoreLang.makeOVERLOADdec.option" compiler bug (this also occurs in 0.78): Transcript: <jhr@bat> cat boot/perv.sml structure Foo = struct val x = InLine.:= end <jhr@bat> smlc Standard ML of New Jersey, Version 0.78, February 26, 1992 (batch compiler) ~mBoot [mBoot()] ... [Compiling boot/perv.sml] structure Foo : ... [closing boot/perv.sml] boot/overloads.sml:4.15-4.21 Error: unbound structure Initial boot/overloads.sml:6.7-6.21 Error: unbound structure Bool in path Bool.makestring boot/overloads.sml:6.27-6.44 Error: unbound structure Integer in path Integer.makestring boot/overloads.sml:6.50-6.64 Error: unbound structure Real in path Real.makestring Error: Compiler bug: CoreLang.makeOVERLOADdec.option [closing boot/overloads.sml] [Failed on "~mBoot" with Syntax] Comment: [dbm] This should never be visible to a user. Status: not a bug ---------------------------------------------------------------------- 532. squaring big real number dumps core on sparc (see also 638) Submitter: rst@ai.mit.edu (Robert S. Thau) Date: 3/24/92 Version: ? System: Sparc Severity: Problem: To repeat this, just attempt to square 1.0E~160 on your nearest sparcstation in SML/NJ. The process will die, complaining that "underflow should not trap". Fix: As I read the source code, the machine-independant signal-handling code (in signal.c) expects floating point underflows not to trap, but the machine- dependant code does enable underflow trapping. Accordingly, here's a one-line fix to SPARC.dep.c in the runtime directory: *** SPARC.dep.c Tue Mar 24 18:08:57 1992 --- SPARC.dep.c.~1~ Tue Aug 20 12:03:52 1991 *************** *** 108,112 **** SETSIG (SIGILL, fpe_handler, mask); #endif MACH ! set_fsr (0x0d000000); /* enable FP exceptions NV, OF & DZ; disable UF */ } --- 108,112 ---- SETSIG (SIGILL, fpe_handler, mask); #endif MACH ! set_fsr (0x0f000000); /* enable FP exceptions NV, OF, UF & DZ */ } Status: fixed in 0.90 ---------------------------------------------------------------------- 533. typing record types Submitter: Richard O'Neill <richard@smaug.questor.wimsey.bc.ca> Date: Tue Mar 24 17:54:13 PST 1992 Version: 0.75 (and 0.73, don't know about 0.78) System: NeXTstation, OS2.1 & Sun4 SunOS 4.1.1. Severity: Major Problem: The type system is *broken* w.r.t. record types. The problem is tied in with use of flex records (but I do NOT mean the 'unresolved flex record in let pattern' business that novice programmers sometimes fail to understand). The type checker gives an incorrect (too general) typing for valid SML. A very minor change causes a correct typing to be given. The best way to show this bug is to give some code that reproduces it: (* * The compiler incorrectly types this function as: * {key:''a,value:'b} list -> {key:''a,value:'c} -> {key:''a,value:'b} list * ^--- should be 'b *) fun insert1 alist (item as {key=desired, ...}) = let (* ^--- remember this bit *) fun worker nil = item :: nil | worker ({key,value} :: items) = if key = desired then item :: items else worker items in (worker alist) end (* * The compiler correctly types this function as: * {key:''a,value:'b} list -> {key:''a,value:'b} -> {key:''a,value:'b} list * ^--- correct *) fun insert2 alist (item as {key=desired, value = _}) = let (* ^--- the only difference *) fun worker nil = item :: nil | worker ({key,value} :: items) = if key = desired then item :: items else worker items in (worker alist) end Transcript: unix% sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "typing-bug.sml" (* Just the source as shown above... *); [opening typing-bug.sml] val insert1 = fn : {key:''a,value:'b} list -> {key:''a,value:'c} -> {key:''a,value:'b} list val insert2 = fn : {key:''a,value:'b} list -> {key:''a,value:'b} -> {key:''a,value:'b} list [closing typing-bug.sml] val it = () : unit - val [{value=foo, ...}] = insert1 nil {key=17, value=100} (* broken *) = and [{value=bar, ...}] = insert2 nil {key=17, value=100} (* okay *) ; std_in:3.1-4.56 Warning: binding not exhaustive {value=bar,...} :: nil = ... std_in:3.1-4.56 Warning: binding not exhaustive {value=foo,...} :: nil = ... val foo = - : 'a val bar = 100 : int - foo : int; val it = 100 : int - foo : string; val it = "d" : string - foo : real; (* This one's cruel, I know... *) Bus error (core dumped) unix% Comment: In practice, it isn't to much of a problem as one can always restrict the type or use the form that types correctly. Even so, it does reflect a problem in the type checker and ought to be fixed. Status: fixed in 0.85 ---------------------------------------------------------------------- 534. .bin files for share and noshare compiler incompatible Submitter: Bernard Sufrin Date: 3/24/92 Version: 0.75 System: Sparc/SUNOS 4.1.1 Severity: minor Problem: I have a good deal of evidence that .bin files compiled by the shared compiler and those compiled by the unshared compiler are incompatible. Shared compiler generated .bin files cause the unshared compiler to crash with a bus error, and vice versa. Status: open ---------------------------------------------------------------------- 535. Problems with non-equality types (bug or language problem?) (see also 341) Submitter: Richard O'Neill <richard@smaug.questor.wimsey.bc.ca> Date: Wed Mar 25 09:41:51 PST 1992 Version: 0.75 (and 0.73, don't know about 0.78) System: NeXTstation, OS2.1 & Sun4 SunOS 4.1.1. Severity: Major Problem: I'm not sure if this is a bug or a language 'feature' - whatever it is, it is certainly unnecessarily restrictive and needs fixing... If I have a reference to a type that does not admit equality, I can still test *references* to that type for equality. But, if that reference is wrapped up as part of a structured type, I cannot. It isn't necessarily tied to references. It also applies to any parametric types which don't actually contain an element of the type, such as: datatype 'a type_only = TypeOnly Take a look at the transcript below... Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - abstype abstract = Abstract with val abstract = Abstract end; type abstract val abstract = - : abstract - val abstract_ref = ref abstract; val abstract_ref = ref - : abstract ref - abstract_ref = abstract_ref; val it = true : bool - - datatype 'a wrapped_ref = WrappedRef of 'a ref; datatype 'a wrapped_ref con WrappedRef : 'a ref -> 'a wrapped_ref - val wrapped_abstract_ref = WrappedRef (abstract_ref); val wrapped_abstract_ref = WrappedRef (ref -) : abstract wrapped_ref - wrapped_abstract_ref = wrapped_abstract_ref; std_in:7.1-7.43 Error: operator and operand don't agree (equality type required) operator domain: ''Z * ''Z operand: abstract wrapped_ref * abstract wrapped_ref in expression: = (wrapped_abstract_ref,wrapped_abstract_ref) - - datatype 'a type_only = TypeOnly; datatype 'a type_only con TypeOnly : 'a type_only - fun equal (x as TypeOnly, y as TypeOnly) = x = y; val equal = fn : ''a type_only * ''a type_only -> bool - (* ^--- doesn't really have to be an equality type *) - Status: not a bug (language problem) ---------------------------------------------------------------------- 536. twig out of date Submitter: wgehrke@risc.uni-linz.ac.at (Wolfgang Gehrke) Date: 3/26/92 Version: 0.75 Problem: I had a small trouble to use twig together with this version of ML. There were two problems: 1) The generated code contains identifiers beginning with '_'. 2) I also changed "invoke.sml" to get a stand alone version. Status: fixed in 0.90 ---------------------------------------------------------------------- 537. System.system fails in noshare compiler after Heap extension Submitter: Eric Madelaine <Eric.Madelaine@sophia.inria.fr> Date: 3/26/92 Version: 0.75 System: sparc Severity: major Problem: When using an sml "-noshare" system, and after the first "Heap extension", any call to System.system fails with: uncaught exception SystemCall This error does not occur before having the heap extended, nor in a system built without the "-noshare" option, even after many heap extensions. [followup on 3/31/92]: It occurs now in any configuration of my system (may be because it is bigger now). Status: fixed in 0.84 ---------------------------------------------------------------------- 538. uncaught exception subscript during compilation Submitter: Dave MacQueen Date: 3/30/92 Version: 0.78 Problem: Code: (* hacked version of code from David Ladd *) (* Variables provide a more sophisticated and better packaged version of ID's *) signature VARIABLES = sig datatype var (* variables *) = PREVBL of string | VBL of {name: string, stamp: int} val varname : var -> string (* following are concerned with "alpha conversion" *) type varenv val newvar: string -> var val empty_env : varenv val lookup : varenv * string -> var option val bind : string * var * varenv -> varenv end structure Variables: VARIABLES = struct (* Rather than represent variables as simple strings, I introduce a variable type (var). The first form (PREVBL) is a temporary variable produced on parsing, and then replaced when static analysis is performed to determine scoping and association between binding and applied occurences of variables. If parsing is made a bit more complicated, this static analysis can be done on the fly during parsing and only the second form of variable would be needed (this is how it is currently done in the ML compiler. For the VBL form, the stamp field is an integer that uniquely identifies that variable. *) datatype var (* variables *) = PREVBL of string | VBL of {name: string, stamp: int} fun varname(PREVBL s) = s | varname(VBL{name,stamp}) = name ^ "." ^ makestring stamp val count = ref 0 fun newvar s = VBL{name=s, stamp=(inc count; !count)} type varenv = (string * var) list val empty_env = [] fun lookup([],_) = NONE | lookup((s,v)::rest,s') = if s = s' then SOME v else lookup(rest,s') fun bind(s,v,env) = (s,v)::env end (* structure Variables *) (* it will probably be more convenient to have a smaller number of cases in the expression datatype. One way of reducing the number of expression constructs is to have an APP constructor that takes an "operator" and a list of argument expressions. If the set of possible operators is fixed, then they may be defined as the constructors of an operator datatype, as below. If new operators can be introduced, then a more complicated operator type would be appropriate. You might look at src/absyn/bareabsyn.sml to see how the ML abstract syntax is defined. Each operator needs to be assigned its arity, and when constructing an expression, or when checking its "well-formedness" (a mild form of type checking), one would verify that the length of the argument list matches the arity of the operator. For proper type checking, each operator would be assigned a type, which would presumably subsume its arity. *) structure Operators = struct datatype operator = PLUS | MINUS | MUL | DIV | MOD | EXP | SHL | SHR | BAND | BOR | XOR | EQ | NEQ | GT | LT | GTE | LTE | AND | OR | IS_IN | UNION | INTERSECTION | SUBSE | SET_EQ | SET_MINUS | MATCH | NOT_MATCH | UMINUS | NOT | BNOT | COUNT | MIN | MAX | SUM (* following function is useful for printing expressions, as in ppexpr *) fun operName PLUS = "plus" | operName MINUS = "minus" | operName MUL = "mul" | operName DIV = "div" | operName MOD = "mod" | operName EXP = "exp" | operName SHL = "shl" | operName SHR = "shr" | operName BAND = "band" | operName BOR = "bor" | operName XOR = "xor" | operName EQ = "eq" | operName NEQ = "neq" | operName GT = "gt" | operName LT = "lt" | operName GTE = "gte" | operName LTE = "lte" | operName AND = "and" | operName OR = "or" | operName IS_IN = "is_in" | operName UNION = "union" | operName INTERSECTION = "intersection" | operName SUBSE = "subse" | operName SET_EQ = "set_eq" | operName SET_MINUS = "set_minus" | operName MATCH = "match" | operName NOT_MATCH = "not_match" | operName UMINUS = "uminus" | operName NOT = "not" | operName BNOT = "bnot" | operName COUNT = "count" | operName MIN = "min" | operName MAX = "max" | operName SUM = "sum" fun arity(oper: operator) : int = case oper of UMINUS => 1 | NOT => 1 | BNOT => 1 | COUNT => 1 | MIN => 1 | MAX => 1 | SUM => 1 | _ => 2 end (* structure Operators *) open Variables Operators (* the rest of this should be packaged in structures too, but its getting late so I'm not going to finish it. *) datatype exp = INT of int (* was CONST *) | STR of string | ENUM of string (* probably want something more specialized than string *) | VAR of var (* was ID *) | QUES of exp * exp * exp | SET of exp list | APP of operator * exp list (* val test = PLUS(CONST(4),CONST(3)); *) val test = APP(PLUS,[INT 4, INT 3]) datatype stmt = ASSERT of exp | FOR of var * exp * stmt | CMPD of stmt list; val testprog = FOR(PREVBL "x",SET([INT(1),INT(2)]), ASSERT(APP(EQ,[VAR(PREVBL "x"),INT 0]))); val testprog2 = FOR(PREVBL "x", SET([INT 1, INT 2]), CMPD([ ASSERT(APP(EQ,[VAR(PREVBL "x"),INT 0])), FOR(PREVBL "x", SET([INT(3),INT(4)]), ASSERT(APP(NEQ,[VAR(PREVBL "x"),INT 1])) ), ASSERT(APP(NEQ,[VAR(PREVBL "x"),INT 1])) ]) ); (* for some useful printing utilities, you might look at src/basics/printutil.sml in the ML source code. But much more sophisticated pretty-printing support is likely to become available soon. *) (* all this concatenating of strings (in a quadratic fashion), is liable to get expensive if you start printing big objects. It is probably more efficient to print directly rather than build a string. There will be an sprintf-style facility in the new library we are building, so you could print "into" a string in a linear fashion. *) (* in src/absyn/printabsyn.sml you can find our rather crude pretty printer for ML abstract syntax. It attempts to cope with infix operators and their precedences and other complications. *) fun prvar (PREVBL s) = s | prvar (VBL{name,stamp}) = name ^ "." ^ makestring stamp fun ppexpr (APP(EQ,[a,b])) = ppexpr a ^" == "^ ppexpr b | ppexpr (APP(NEQ,[a,b])) = ppexpr a ^" != "^ ppexpr b | ppexpr (INT i) = makestring i | ppexpr (STR s) = "\"" ^ s ^ "\"" | ppexpr (VAR v) = prvar v | ppexpr (SET l) = "{" ^ pplist l ^ "}" | ppexpr (QUES(e1,e2,e3)) = "if " ^ ppexpr e1 ^ " then " ^ ppexpr e2 ^ " else " ^ ppexpr e3 | ppexpr (APP(oper,args)) = operName oper ^ "(" ^ pplist args ^ ")" (* here you see the advantage of separating out the operators *) and pplist ([h]) = ppexpr h (* shorthand for h::[] *) | pplist (h::t) = ppexpr h ^ "," ^ pplist t | pplist [] = "" (* this could be made a bit more efficient. We probably need to provide a primitive to efficiently build such strings. fun sp 0 = "" | sp n = " " ^ sp (n - 1); Below is a somewhat faster version (especially as n gets larger. *) fun sp n = let fun collect(0,l) = l | collect(n,l) = collect(n-1," "::l) in implode(collect(n,[])) end fun ppstmt (t,ASSERT(x)) = "\n" ^ sp t ^ ppexpr x ^ ";" | ppstmt (t,FOR(a,b,c)) = "\n"^ sp t ^"for " ^ (varname a) ^ " in " ^ ppexpr b ^ ppstmt(t+1,c) | ppstmt (t,CMPD(nil)) = "" | ppstmt (tab,CMPD(l)) = let fun pplist (h::t) = ppstmt(tab,h) ^ pplist t | pplist [] = "" in " begin" ^ pplist l ^ "\n" ^ sp (tab - 1) ^ "end" end; fun prt (ex) = output(std_out,ppstmt(0,ex) ^ "\n"); (* to complete this evaluator sensibly you need a more general notion of the values that your expressions can evaluate to. Presumably you need to deal with strings, booleans, and set values in addition to integers. The value type will probably be a datatype. *) datatype value = INTval of int | STRval of string | BOOLval of bool | SETval of value list (* allows heterogeneous sets, which probably don't occur. *) fun seval (INT x) = INTval x | seval (APP(PLUS,[a,b])) = let val INTval va = seval a and INTval vb = seval b in INTval(va+vb) end | seval (APP(MINUS,[a,b])) = let val INTval va = seval a and INTval vb = seval b in INTval(va-vb) end | seval (QUES(x,y,z)) = let val INTval vx = seval x and INTval vy = seval y and INTval vz = seval z in INTval(if vx <> 0 then vy else vz) end | seval (_) = INTval 0; (* ??? *) (* what types of values does an operator like EQ apply to? If it is overloaded, and can apply to, say, integers and strings, then the evaluation rule has to do a case analysis: | seval (APP(EQ,[a,b])) = case seval a of INTval va => (case seval b of INTval vb => BOOLval(va = vb) | _ => raise TypeError) | STRval va => (case seval b of STRval vb => BOOLval(va = vb) | _ => raise TypeError) | ... *) fun eaconv env (e as VAR(PREVBL x)) = (case lookup(env,x) of SOME v => VAR v | NONE => e) | eaconv env (APP(oper,args)) = APP(oper, map (eaconv env) args) | eaconv env (QUES(e1,e2,e3)) = QUES(eaconv env e1, eaconv env e2, eaconv env e3) | eaconv env (SET elems) = SET(map (eaconv env) elems) | eaconv env e = e fun alphasub (env,ASSERT(x)) = ASSERT(eaconv env x) | alphasub (env,CMPD(l)) = let fun mapped(x) = alphasub(env,x) in CMPD(map mapped l) end | alphasub (env,FOR(PREVBL a, b, c)) = let val new = newvar a in FOR(new, (eaconv env b), alphasub( bind(a,new,env), c)) end | alphasub (env,stmt) = stmt; fun aconv(x) = alphasub(empty_env,x); Status: fixed in 0.83 ---------------------------------------------------------------------- 539. weak typing bug Submitter: John Greiner Date: 4/2/92 Version: 0.75 Severity: major Problem: weak typing failure Transcript: - (let val x = ref nil in fn y => x end) (); val it = ref [] : '1a list ref - let val a = (let val x = ref nil in fn y => x end) () in = a:=[1]; hd(!a)^"hi" end; val it = "\^Ahi" : string In V.73 (I think) this wasn't there, as I have referenced in a file: - (let val x = ref nil in fn y => x end) (); std_in:2.1-2.41 Error: nongeneric weak type variable it : '~1Z list ref Status: fixed in 0.89 ---------------------------------------------------------------------- 540. printing hanging on Mach Submitter: Bob Harper Date: 4/2/92 Version: 0.78 System: DecStation 5000, Mach, running over telnet Severity: major Problem: Type "structure S = System". On my machine it prints about halfway through, then hangs. Comment: Sometimes when running sml over a telnet, the printing hangs. You can continue by typing space. This is not new to 0.78. [Gene Rollins] [Bob Harper, 4/11/92]: Incidentally, on the PMAX (at least) I consistently get the following behavior. I type in something, particularly something that incurs a type error. I get back half or three quarters of a message, then it hangs. The only way out is to type ^C, which gets me back to the prompt. If I type the same thing again, I may or may not get the full message. Often I just kill the session and start over, then it works (for a while). We're running Mach on the PMAX, and I'm using ML via telnet, within an emacs ML interaction window, if it matters. Status: fixed in 0.84 ---------------------------------------------------------------------- 541. warnings while compiling runtime Submitter: Kai Kein{nen <kmk@cc.tut.fi> Date: April 5, 1992 Version: 0.80 from research.att.com:/dist/ml/working on April 5 System: RISC/OS 4.52, MIPS RC 6280 Severity: minor Problem: compilation time warnings for gc.c and prim.s Code: ./makeml -mips riscos Transcript: ./makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run ./makeml> rm -f mo ./makeml> ln -s ../mo.mipsb mo ./makeml> (cd runtime; rm -f run allmo.o allmo.s) ./makeml> (cd runtime; make MACHINE=MIPS 'CFL= -systype bsd43' 'LIBS=' 'DEFS= -DRISCos -DRUNTIME=\"runtime\"' linkdata) cc -O -systype bsd43 -DMIPS -DRISCos -DRUNTIME=\"runtime\" -o linkdata linkdata.c ./makeml> runtime/linkdata [runtime/IntMipsBig.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o ./makeml> (cd runtime; make MACHINE=MIPS 'DEFS= -DRISCos' 'CPP=/lib/cpp -P' 'CFL= -systype bsd43' 'AS=as' 'LIBS=') cc -O -systype bsd43 -DMIPS -DRISCos -c run.c cc -O -systype bsd43 -DMIPS -DRISCos -c run_ml.c cc -O -systype bsd43 -DMIPS -DRISCos -c callgc.c cc -O -systype bsd43 -DMIPS -DRISCos -c gc.c uopt: Warning: gc: this procedure not optimized because it exceeds size threshold; to optimize this procedure, use -Olimit option with value >= 886. cc -O -systype bsd43 -DMIPS -DRISCos -c MIPS.dep.c cc -O -systype bsd43 -DMIPS -DRISCos -c export.c cc -O -systype bsd43 -DMIPS -DRISCos -c timers.c cc -O -systype bsd43 -DMIPS -DRISCos -c ml_objects.c cc -O -systype bsd43 -DMIPS -DRISCos -c cfuns.c cc -O -systype bsd43 -DMIPS -DRISCos -c cstruct.c cc -O -systype bsd43 -DMIPS -DRISCos -c signal.c cc -O -systype bsd43 -DMIPS -DRISCos -c exncode.c cc -O -systype bsd43 -DMIPS -DRISCos -c malloc.c cc -O -systype bsd43 -DMIPS -DRISCos -c mp.c cc -O -systype bsd43 -DMIPS -DRISCos -c sync.c /lib/cpp -P -DASM -DMIPS -DRISCos MIPS.prim.s > prim.s as -o prim.o prim.s as0: Warning: prim.s, line 305: missing .end preceding this .ent: set_request .ent set_request as0: Warning: prim.s, line 305: .ent/.end block never defined the procedure name as0: Warning: prim.s, line 434: missing .end preceding this .ent: go .ent go Comments: Some of the corrections needed earlier for MIPS R6000 seem to be missing from this version. The interpreter seems to work correctly in spite of these warnings. Status: fixed in 0.90 ---------------------------------------------------------------------- 542. lack of environment cleanup in 0.80 Submitter: schristensen@daimi.aau.dk (Soren Christensen) Date: 4/6/92 Version: 0.80 Severity: major Problem: The other question is related to a problem I had in 0.75: >fun x 0 = () | x n = (use_stream (open_string "3"); x (n-1)); >fun test () = (exportML "pre"; x 1000; exportML "post"); > >Try test(); and check the diff in size of pre and post. There seems to be a more grneral problem in 0.80. The toplevel environment seems to grow - even if I do not declare new names. Now that I can inspect the valuse in the environmet I find "VAL$it" repeted. try: map (fn x => print (System.Symbol.makestring x))(System.Env.catalogEnv (System.Env.staticPart (!System.Env.topLevelEnvRef))); Especially after running for a while. Status: fixed in 0.82 ---------------------------------------------------------------------- 543. top-level printing fails Submitter: Bob Harper Date: 4/8/92 Version: ? Severity: major Problem: Code: type OrdId = string type ModId = string datatype Ord = Kind | Type | Pi of Dec * Ord | Abs of Dec * Ord | App of Ord * Ord | Cast of Ord * Ord | One | Sub of Ord * Sub | Fst of Mod and Mod = KindM | Signature | PiM of DecM * Mod | AbsM of DecM * Mod | AppM of Mod * Mod | OneM | CastM of Mod * Mod | SubM of Mod * Sub | Nil | NilSig | OTuple of Def * Mod | OTupleSig of Dec * Mod | RTuple of DefM * Mod | RTupleSig of DecM * Mod | FstM of Mod | SndM of Mod and Sub = Id | Shift | ODef of Sub * (OrdId * Ord * Ord option) | MDef of Sub * (ModId * Mod * Mod option) | Comp of Sub * Sub and Ctx = Null | ODec of Ctx * Dec | MDec of Ctx * DecM and Dec = Dec of OrdId * Ord and Def = Def of OrdId * Ord and DecM = DecM of ModId * Mod and DefM = DefM of ModId * Mod ; Transcript: I type: val S = OTupleSig(Dec("t",Type),NilSIg); I get: val S = OTupleSig ( uncaught exception Subscript The actual input is much larger: I build the system using SourceGroup, then open the structure IntSyn, which makes available this datatype, which then results in the exhibited behavior. Status: fixed in 0.84 ---------------------------------------------------------------------- 544. poor error message Submitter: John Reppy Date: 4/16/92 Version: 0.81 Severity: minor Problem: The error message Error: non-constructor applied to argument in pattern would be much more useful if it gave the name of the identifier. Comment: [dbm, 10/7/92] There are two places where this message was generated. In elabutil.sml code has been added to print the bogus rator. In astutil.sml the message has been changed to "nonidentifier applied to argument in pattern", but bogus pattern is not printed because there is no ast printer yet. Status: open (patially fixed in 0.91) ---------------------------------------------------------------------- 545. signature matching looping? Submitter: Amy Moormann Zaremski <amy+@cs.cmu.edu> Date: Mar 5, 1992 Version: .75 (both with and without sourcegroup) System: Dec 3100, Mach ??(whatever default is right now) Severity: minor Problem: Certain signature/structure combinations cause SML to "loop" (grow the heap until memory is exhausted). Code: signature S = sig val f : 'b -> int end structure S1:S = struct fun f x = x end Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - signature S = sig = val f : 'b -> int = end; signature S = sig val f : 'a -> int end - structure S1:S = struct = fun f x = x = end; [Major collection... [Increasing heap to 2478k] [Increasing heap to 4798k] 92% used (1550460/1673392), 1188 msec] [Increasing heap to 7002k] [Major collection... 74% used (2960732/3949436), 2797 msec] [Increasing heap to 11582k] [Major collection... [Increasing heap to 17730k] 80% used (5808988/7231036), 5062 msec] [Increasing heap to 21198k] [Major collection... [Increasing heap to 32438k] 80% used (10635356/13238652), 9407 msec] [Increasing heap to 32634k] [Major collection... 73% used (13238652/17984796), 12468 msec] [Increasing heap to 32710k] [Major collection... [Increasing heap to 32734k] [Increasing heap to 32746k] [Increasing heap to 32750k] [Increasing heap to 32754k] Warning: can't increase heap Ran out of memory Process Inferior smlsg exited abnormally with code 3 Status: fixed in 0.83 ---------------------------------------------------------------------- 546. System.architecture not initialized Submitter: Gene Rollins, Dave MacQueen Date: 4/24/92 Version: 0.81 Severity: minor Problem: System.architecture not initialized because comment brackets in cps/shareglue.sml haven't been removed. Status: fixed in 0.81 ---------------------------------------------------------------------- 547. interrupt not working (inside emacs) Submitter: slind@research.att.com Date: April 27, 1992 Version: 81 System: mips (It doesn't occur on the sun4) Severity: major Problem: 1) In gnu emacs, sml goes into an infinite loop when I hit the interrupt key, i.e., on the DEL character. Then sml seems to ignore signals: the only way to regain control is to kill the sml process. Merely exiting emacs will not kill the sml process. 2) A related problem is that interrupt doesn't give the right exception (and not until a carriage return): it returns the Abort exception. Transcript: 1) (Inside gmacs.) $ sml Standard ML of New Jersey, Version 0.81, 9 April 1992 Arrays have changed; see Release Notes val it = () : unit - \003 \003 \004 2) (In the shell) $ sml Standard ML of New Jersey, Version 0.81, 9 April 1992 Arrays have changed; see Release Notes val it = () : unit - <DEL key struck: nothing happens; now issue a CR> std_in:3.1 Error: illegal token uncaught exception Abort - Status: fixed in 0.82 (same as 550) ---------------------------------------------------------------------- 548. blast_read on ints Submitter: slind@research.att.com Date: April 28, 1992 Version: 75, 81 System: mips and sparc at least; probably all Severity: minor Problem: System.Unsafe.blast_X (where X probably = "read", but I'm not sure). Solitary ints aren't handled properly: in 81, core gets dumped; in 75, the wrong value is returned. Transcript: In 81: $ sml Standard ML of New Jersey, Version 0.81, 9 April 1992 Arrays have changed; see Release Notes val it = () : unit - val outs = open_out "foo"; val outs = - : outstream - System.Unsafe.blast_write(outs,1); [Major collection...abandoned] val it = () : unit - close_out outs; val it = () : unit - val ins = open_in "foo"; val ins = - : instream - System.Unsafe.blast_read ins : int; Memory fault - core dumped $ In 75: - val outs = open_out "foo"; val outs = - :outstream - System.Unsafe.blast_write(outs,1); [Major collection...abandoned] val it = () :unit - close_out outs; val it = () :unit - val ins = open_in "foo"; val ins = - :instream - System.Unsafe.blast_read ins : int; val it = 3242475 :int - Status: fixed in 0.86 ---------------------------------------------------------------------- 549. Match exception while compiling Submitter: jont@uk.co.harlqn Date: 28/04/92 Version: SML of NJ version 0.75 System: Sun 4/330 with SunOS 4.1.1 Severity: minor Transcript: - val _ = =; std_in:1.9 Error: nonfix identifier required uncaught exception Match Comment: I guess this shouldn't happen. It's not the sort of thing I type regularly, I was prompted to do it by the compiler's habit of inserting = all over the place when it thinks I've left out an identifier. Comment: in 0.89 produces following - val _ = = ; std_in:0.0 Error: nonfix identifier required Error: Compiler bug: elabVB - Status: fixed in 0.91 (dbm) ---------------------------------------------------------------------- 550. interrupt on MIPS Submitter: Lal George Date: 4/29/92 Version: 0.81 System: MIPS/Riscos 4.52 Severity: major Problem: 0.81 on the MIPS has problems with signal handling. An interrupt (ctrl-c) causes it to go into deep space, eating up cpu time. Status: fixed in 0.82 ---------------------------------------------------------------------- 551. large integers yield Illegal instruction Submitter: Kjeld H. Mortensen | Email: kjeld@metasoft.com Date: 4/29/92 Version: 0.81 System: ? Severity: major Problem: Large integer literal causes illegal instruction. Transcript: metasparc 141 : /d1/tools/njsml/81/sml.sparc.ns Standard ML of New Jersey, Version 0.81, 9 April 1992 Arrays have changed; see Release Notes val it = () : unit - 536870911; val it = 536870911 : int - 536870912; Illegal instruction metasparc 142 : Comments: 536870912 seems to be 2^29. (Similar behaviour, of course, for corresponding negative numbers.) This compiler was build with 'makeml -noshare' on a Sun4, but compilers build with 'makeml' have same behaviour. In SML/NJ v0.80 this is no problem. Here integers can be up to (2^30)-1 and it doesn't give 'Illegal instruction'. Status: Fixed in 0.81 (?) ---------------------------------------------------------------------- 552. Error message line numbers from std_in (see also 575) Submitter: Lal George Date: 30th April, '92 Version: 0.81 System: all Severity: major Problem: Error line numbers are incorrect in the interactive session. Transcript: Standard ML of New Jersey, Version 0.81, 9 April 1992 Arrays have changed; see Release Notes val it = () : unit - val x = 1; val x = 1 : int - fun f x = val y = 2 in x + y end; --> std_in:4.11 Error: syntax error found at VAL - val x = 3; val x = 3 : int - val x = 4; val x = 4 : int - fun f x = val y = 2 in x + y end; --> std_in:6.12 Error: syntax error found at VAL Comments: This is a nuisance for programs that do regression testing, or under emacs ML-mode. Status: fixed in 0.91 ---------------------------------------------------------------------- 553. incorrect syntax accepted Submitter: John Reppy Date: 4/30/92 Version: 0.81a Severity: minor Problem: The following things are not legal SML syntax, but we accept them: Transcript: Standard ML of New Jersey, Version 0.81, 9 April 1992 Arrays have changed; see Release Notes val it = () : unit - let in 1 end; val it = 1 : int - let ; in 1 end; val it = 1 : int - let ;;; in 1 end; val it = 1 : int - Fix: change "LET ldecs IN " to "LET ldec ldecs IN" Note that there are probably two places where this occurs; the other is "LET sdecs IN" or something like that. Note: the Definition allows an "empty declaration" so this isn't a bug. Status: not a bug ---------------------------------------------------------------------- 554. unused token constructor QUERY Submitter: John Reppy Date: 4/29/92 Version: 0.81a Severity: trivial Problem: I notice that there is a terminal symbol named QUERY declared in ml.grm, which is never used. Fix: remove QUERY constructor Status: fixed in 0.90 ---------------------------------------------------------------------- 555. window signal Submitter: John Reppy (jhr@research.att.com) Date: May 8, 1992 Version: versions 75-81 (at least) System: RISCOS (R3000 & R6000) Severity: major Problem: resizing a shell window (xterm or cmdtool) that is running sml causes the sml process to either die or go into an infinite loop. Comments: This is likely a problem with the handling of WINCH signals, but it doesn't seem to be related to the general problems with signals on the MIPS in 0.81. Status: fixed in 0.82 ---------------------------------------------------------------------- 556. large integers on Sparc Submitter: <Sven Doerr, Univ. Karlsruhe, Germany; sd@ira.uka.de> Date: <Tue May 12 14:43:25 MET DST 1992> Version: <SML of NJ version number, 0.81> System: <sun4, SunOS Release 4.1.1> Severity: <minor> Problem: <typing large integers at top level or arithmetic overflow aborts sml with: Illegal instruction> Code: < 0x80000000 <return> > Transcript: < Standard ML of New Jersey, Version 0.81, 9 April 1992 Arrays have changed; see Release Notes val it = () : unit - 100000 * 100000; Illegal instruction > Status: fixed in 0.83 ---------------------------------------------------------------------- 557. sparc signals Submitter: Andre Kramer akramer@ecrc.de Date: Thu May 14 Version: 0.75 System: sparc Severity: <minor, major, or critical> Problem: asynchronous exceptions for sparc file SPARC.prim.s _savefpregs retl nop does nothing. in signal.c /* * save floating point registers. */ savefpregs(msp); fpregs = ((int *)(msp->ml_allocptr)) + 1; msp->ml_allocptr += (NSAVED_FPREGS*2 + 1) * sizeof(int); allocates 1 word from heap and later saves a pointer to it (fpregs). this word should contain a descriptor (len 0,tag string): Fix: (MAKE_DESC(NSAVED_FPREGS*8,tag_string)) as is done in _savefpregs for the M68, MIPS. (VAX is same as Sparc). Comments: I have a another question on the new calling conventions (CALLEESAVE) for sparc. If register masks in code strings don't contain the CLOSURE_INDX the last bit is 0. A mask then either looks like a pointer or an int. Does this not affect the garbage collector? Status: fixed in some version between 0.75 and 0.81 ---------------------------------------------------------------------- 558. local...end structure expressions not working in 0.80 Submitter: Tim Freeman, tsf@cs.cmu.edu Date: Fri May 15 14:38:42 1992 Version: 0.80 System: Sun 4 running Mach Severity: minor Problem: The new compiler doesn't know that local...end is sensible at the structure level. Transcript: val it = () : unit - System.Compile.makeSource ("foo",1,std_in,true,std_out); val it = prim? : source - val staticEmpty = System.Env.staticPart (System.Env.emptyEnv ()); val staticEmpty = prim? : staticEnv - val s = System.Compile.makeSource ("foo",1,std_in,true,std_out); val s = prim? : source - System.Compile.compile (s,staticEmpty); - local = structure x = struct val z = 3 end = in = structure y = struct val w = x.z end = end; uncaught exception Compile Status: fixed in 0.84 ---------------------------------------------------------------------- 559. static environment not cleaned up Submitter: Dave MacQueen Date: 5/17/92 Version: 0.81 Severity: average Problem: Top level static environment is not consolidated in the interactive loop, so hidden static bindings are not removed and static environment grows too fast. Fix: Add a call of Environment.consolidate when newenv is built at the end of function evalLoop in functor Interact (build/interact.sml). Status: fixed in 0.84 ---------------------------------------------------------------------- 560. blast functions and separate compilation Submitter: Emden R. Gansner, erg@ulysses.att.com Date: 18 May 1992 Version: 0.81c System: Sparc 2, SunOS 4.1 Severity: major Problem: Separate compilation facility is broken Code: structure SepComp = struct val fname = "a.o" fun compFile () = let open System.Compile System.Env val targetWrite : (outstream * compUnit) -> unit = System.Unsafe.blast_write val staticPerv = staticPart(!pervasiveEnvRef) val sourceF = open_string "structure A = struct end" val source = makeSource("", 1, sourceF, false, std_out) val compUnit as (static, code) = (compile(source,staticPerv)) handle e => (closeSource source; raise e) val outstr = open_out fname in targetWrite (outstr, compUnit); closeSource source; close_out outstr end fun loadFile () = let open System.Compile val targetRead : instream -> compUnit = System.Unsafe.blast_read val instr = open_in fname val effectiveEnv = !System.Env.pervasiveEnvRef val _ = print "starting load \n" val (staticUnit,codeUnit) = targetRead instr in print "readUnit done \n"; close_in instr; print "starting execute \n"; execute((changeLvars staticUnit,codeUnit), effectiveEnv); print "finished execute \n" end end val _ = SepComp.compFile () val _ = SepComp.loadFile () Transcript: loadFile hangs during execute; sending an interrupt signal produces a core dump Comments: This program works fine in 0.80. Changes made to blast_read and blast_write in 0.81 are probably the root of the problem. The above program also failed in 0.81b, but hung during blast_read. This was mentioned to Lal, who, I believe, produced 0.81c as a partial fix. Status: fixed in 0.82 ---------------------------------------------------------------------- 561. exportFn images too big (same as 489) Submitter: Andrew Koenig Date: 5/19/92 Version: 0.75 System: Sparc Severity: minor Problem: For practical reasons, it would be nice to get exportFn to create less bulky executables for small programs. For example, here is a somewhat simplified version of the `echo' command: fun echo [] = print "\n" | echo (h::nil) = print (h^"\n") | echo (h::t) = (print(h ^ " "); echo t) fun main(argv, envp) = echo(tl argv) When I use `exportFn' to make an executable of this, it takes 136 kbytes using 0.53 on a 10th Edition machine. Using 0.75 on a Sparcstation, the executable is 471 kbytes. Even if we allow that Sparc executables are bigger, it is hard to believe that that much baggage is truly necessary. [from ark, 12/1/92:] I just built 0.92 and gave it a try. When built with -noshare, the following fun main _ = print "Hello world\n"; exportFn ("xxx", main); yields a 946K executable with 860K of loadable data. This is as opposed to 376K/249K with 0.75, which in turn was about twice as big as 0.43. [from Lal, 12/16/92] We mercifully had the result of exportFn for the lego theorem prover using version 0.66. So I built a noshare version of sml for the Sparc and rebuilt lego using version 0.92. There is more than a Mbyte increase in the size of the exported image. Below, Olego is the image under 0.66, and lego is the version under 0.92. Either this is to be expected - which is bad, or there are references that are not being cleared - which is also bad. ---------------------------------------------------------------- lutece:$ ls -l total 3104 -rwxrwxrwx 1 dbm 999456 Mar 26 1991 Olego* -rwxr-xr-x 1 george 2146336 Dec 16 18:38 lego* Status: fixed in 0.93c ---------------------------------------------------------------------- 562. SML hanging under telnet (under Mach) (also #540) Submitter: tsf@cs.cmu.edu Date: Tue May 19 15:14:55 1992 Version: 0.80 System: Pmax, running Mach. Also Sun 4's running mach, but more rarely. (I'm referring to the type of the machine running SML, not the type of the machine running telnet.) Severity: minor Problem: When running under telnet, sml intermittently hangs on output. Code: Anything that produces lots of output will do. Transcript: It's long, so I put it at the end of this message. It's not very informative. Comments: If I say "sml | cat -u" instead of "sml", things work fine. If I create a remote xterm and run sml within that, or a remote gnu-emacs and run sml within that, things work fine. The problem only happens when sml's standard output is a pty controlled by telnet. The type of the machine running sml seems to make more of a difference than the type of the machine at the other end of the telnet connection. Fix: Say "sml | cat -u" instead of "sml" to invoke sml at the other end of a telnet connection. Looking at the code for flushbuf in boot/perv.sml, I see that you wait for output to become possible before sending the first bytes of output, but inside the loop in write_all in runtime/cfuns.c, you don't wait for output to become possible after a partial write. This discrepancy is strange, but I don't see how it could give rise to this bug. Do you use nonblocking IO? Why do you wait for output to become possible before starting a write? I wouldn't be surprised if telnet is the only device you output to that doesn't always write all of the bytes you ask it to. Here's the transcript. The details don't matter much, anything that produces this much chatter is very likely to hang. This works fine when run locally or when piped through "cat -u". % telnet desert.fox Trying 128.2.206.48... Connected to DESERT.FOX.CS.CMU.EDU. Escape character is '^]'. DESERT.FOX.CS.CMU.EDU TCP Telnet service. 4.3 BSD UNIX (DESERT.FOX.CS.CMU.EDU) (ttyP0) login: tsf Password: Last login: Thu May 14 13:11:17 from 128.2.222.175 (*Unknown*) This login: Tue May 19 14:28:07 from 128.2.222.175 (*Unknown*) % sml-sg Standard ML of New Jersey, Version 0.80, April 2, 1992 with SourceGroup 2.1b built on Fri May 8 10:02:15 EDT 1992 val it = () : unit - use "load.sml"; [closing /afs/cs/user/tsf/sml/lib/setparams.sml] Eof val it = () : unit /afs/cs/user/tsf/sml/lib/link.sml /afs/cs/user/tsf/sml/lib/subst.sig.sml /afs/cs/user/tsf/sml/lib/subst.sml /afs/cs/user/tsf/sml/lib/util.sig.sml /afs/cs/user/tsf/sml/lib/util.sml val libg = 1 : ?.group val makeload = fn : unit -> unit [closing /afs/cs/user/tsf/sml/lib/lib.sml] Eof val it = () : unit refine.lex.sml refine.grm.sig refine.grm.sml unify.sml unify.sig.sml term.sml term.sig.sml subtypedata.sml subtypedata.sig.sml subtype.sml subtype.sig.sml parse.sml parse.sig.sml mltype.sml mltype.sig.sml link.sml interface.sml interface.sig.sml interactive.sml base.sml absyn.sml absyn.sig.sml refine.lex refine.grm val newg = 3 : ?.group val loadref = fn : unit -> unit [reading /afs/cs/user/tsf/sml/lib/.@sys/util.sig.sml.bin] signature UTIL [reading /afs/cs/user/tsf/sml/lib/.@sys/util.sml.bin] functor Util [reading /afs/cs/user/tsf/sml/lib/.@sys/subst.sig.sml.bin] signature SUBST [reading /afs/cs/user/tsf/sml/lib/.@sys/subst.sml.bin] functor Subst [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/term.sig.sml.bin] signature TERM [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/unify.sig.sml.bin] signature UNIFY [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/unify.sml.bin] functor Unify [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/term.sml.bin] functor Term [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/subtypedata.sig.sml.bin] signature SUBTYPEDATA [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/subtypedata.sml.bin] functor SubtypeData [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/mltype.sig.sml.bin] signature MLTYPE [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/subtype.sig.sml.bin] signature SUBTYPE [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/subtype.sml.bin] functor Subtype [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/base.sml.bin] signature LR_PARSER functor Join signature ARG_PARSER signature STREAM signature FIFO functor JoinWithArg signature TOKEN <other binding> <other binding> signature PARSER_DATA signature LR_TABLE <other binding> signature PARSER signature LEXER signature ARG_LEXER [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/refine.grm.sig.bin] signature Refine_LRVALS signature Refine_TOKENS [reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/interface.sig.sml.bin] (and it hanged here! Pressing ^C unhangs it and returns me to the top level.) Status: fixed in 0.84 ---------------------------------------------------------------------- 563. trig functions return garbage on large args Submitter: Andrzej Filinski, andrzej@cs.cmu.edu Date: May 29, 1992 Version: 0.75 (also in 0.80) System: all Severity: minor Problem: trig. functions return huge, random results for arguments greater than approx. 6.747E9 (= 2 pi * maxint). Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - sin 6.746E9; val it = 0.577192771297902 : real (* correct to about 6 significant digits, as expectable *) - sin 6.747E9; val it = ~1.17525075405876E64 : real Comments: The problem seems to be with the overflow handling in rtoi/drem, file boot/math.sml. Status: fixed in 0.84 ---------------------------------------------------------------------- 564. problems on HP9000s400 Submitter: Kjeld H. Mortensen (kjeld@metasoft.com) Date: 6/2/92 Version: 0.81 System: HP9000s400, HPUX 8.0, 32Mb ram, >70Mb swap Severity: minor (but might be major for other people) Problem: Bug in sun2hp.el Code: Do a 'makeml -m68 hpux8' Transcript: neptune 125 : makeml -m68 hpux8 makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.m68 mo makeml> (cd runtime; rm -f run allmo.o allmo.s) makeml> (cd runtime; make MACHINE=M68 'CFL=-Wl,-a,archive' 'LIBS=' 'DEFS= -DHPUX -DRUNTIME=\"runtime\"' linkdata) cc -g -Wl,-a,archive -DM68 -DHPUX -DRUNTIME=\"runtime\" -o linkdata linkdata.c (cd runtime; grep -v mo/Math.mo IntM68.mos > Tmp.mos) makeml> runtime/linkdata [runtime/Tmp.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o makeml> (cd runtime; ...) makeml> /lib/cpp -DCALLEESAVE=0 -DM68 -DHPUX -DASM M68.prim.s > prim.s makeml> emacs -batch -l sun2hp.el prim.s prim.s label <2> has moved makeml> as -o prim.o prim.s as error: "prim.s" line 255: invalid instruction mnemonic (.text) as error: "prim.s" line 255: syntax error [...rest of error msgs deleted...] Comments: "label <2> has moved" is printed by the LISP fn replace-all-label-definitions. It gets confused because there are more than one label on a line (this kind of lines with multible labels are produced by the (new) macro "CHECKLIMIT" in M68.prim.s). Fix: Replace replace-all-label-definitions with the following fn: (the fix does the following: instead of moving to the beginning of the line in order to search for the label, the pointer is only moved 2 chars to the left of the label.) ;; replace-all-label-definitions -- change each of the old label ;; definitions to their new value. ;; (defun replace-all-label-definitions (labels) (while labels (let* ((cur (car labels)) (old-label (label-old-label cur)) (point (label-point cur)) (new-label (label-new-label cur))) (goto-char (- point 2)) (re-search-forward "\\([0-9]+\\):" (point-max) t) (if (not (string-equal (buffer-substring (match-beginning 1) (match-end 1)) old-label)) (error "label <%s> has moved" old-label) (replace-match (concat new-label ":")))) (setq labels (cdr labels)))) [Reppy:] Probably the easiest fix for this is to change the CHECKLIMIT macro to #define CHECKLIMIT \ 1: \ jgt 2f; \ lea 1b,a5; \ rts; \ 2: [Mortensen:] I don't think this will work since /lib/cpp on the HP9000s400 (at least on ours) converts CHECKLIMIT into 1: jgt 2f; lea 1b,a5; rts; 2: If sun2hp.el is fixed, anybody can make changes to M68.prim.s without having to remember that multible labels on a line are not allowed, just because the translator algorithm in sun2hp.el cannot handle it. Status: fixed in 0.87 ---------------------------------------------------------------------- 565. System.Directory.listDir on SGI Submitter: John Reppy (jhr@research.att.com) Date: June 4, 1992 Version: 0.81 System: SGI 3D/480, SGI Crimson (Irix 4.0.1, 4.0.4) Severity: major Problem: Using the function System.Directory.listDir causes sml to go into an uninterruptable infinite loop. Transcript: <transcript of session illustrating problem> Standard ML of New Jersey, Version 0.81, 15 May 1992 val it = () : unit - System.Directory.listDir "."; Comments: This code often seems to be flakey. Maybe we should switch to using the underlying OS code. Status: fixed ---------------------------------------------------------------------- 566. An addition to sun2hp.el (?) Submitter: Kjeld H. Mortensen (kjeld@metasoft.com) Date: 6/2/92 Version: 0.81 System: HP9000s400, HPUX 8.0, 32Mb ram, >70Mb swap Severity: minor (but might be major for other people) Problem: Tranlation entry missing in sun2hp.el Code: Do a 'makeml -m68 hpux8' with the fix to sun2hp.el I send earlier Transcript: neptune 126 : makeml -m68 hpux8 makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.m68 mo makeml> (cd runtime; rm -f run allmo.o allmo.s) makeml> (cd runtime; make MACHINE=M68 'CFL=-Wl,-a,archive' 'LIBS=' 'DEFS= -DHPUX -DRUNTIME=\"runtime\"' linkdata) cc -g -Wl,-a,archive -DM68 -DHPUX -DRUNTIME=\"runtime\" -o linkdata linkdata.c (cd runtime; grep -v mo/Math.mo IntM68.mos > Tmp.mos) makeml> runtime/linkdata [runtime/Tmp.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o makeml> (cd runtime; ...) makeml> /lib/cpp -DCALLEESAVE=0 -DM68 -DHPUX -DASM M68.prim.s > prim.s makeml> emacs -batch -l sun2hp.el prim.s prim.s Wrote /d1/release/tools/njsml/workatt81/src/runtime/prim.s makeml> as -o prim.o prim.s as error: "prim.s" line 420: invalid instruction mnemonic (jpl) as error: "prim.s" line 420: syntax error as error: "prim.s" line 458: invalid instruction mnemonic (jpl) as error: "prim.s" line 458: syntax error as error: "prim.s" line 479: invalid instruction mnemonic (jpl) as error: "prim.s" line 479: syntax error as error: "prim.s" line 500: invalid instruction mnemonic (jpl) as error: "prim.s" line 500: syntax error as error: "prim.s" line 527: invalid instruction mnemonic (jpl) as error: "prim.s" line 527: syntax error Comments (+Fix?): The intruction "jpl" is not know to the sun2hp translator (in fn do-subst). I don't know what jpl is supposed to do, but my _guess_ is that it should be translated into the branch instruction "bpl.w" (anologious to transl. of jeq, jge, ... etc.). Shouldn't the line (replace-re "\\<jpl" "bpl.w") be added to the fn do-subst in sun2hp.el? Status: fixed in 0.90 ---------------------------------------------------------------------- 567. makeml does not succeed on HPUX (680x0 problem) Submitter: Kjeld H. Mortensen (kjeld@metasoft.com) Date: 6/2/92 Version: 0.81 System: HP9000s400, HPUX 8.0, 32Mb ram, >70Mb swap Severity: minor (but might be major for other people) Problem: A makeml does not succeed (exception raised in Loader) Code: Do a 'makeml -m68 hpux8' with the two fixes to sun2hp.el I send earlier Transcript: >From time to time, I get different results: --- > makeml -m68 hpux8 [...stuff deleted...] signature CLEANUP = ... signature WEAK = ... signature SUSP = ... signature POLY_CONT = ... signature UNSAFE = ... signature SYSTEM = ... [closing boot/system.sig] signature MATH = ... structure Math : MATH [closing boot/math.sml] [Major collection... 20% used (339576/1680172), 250 msec] uncaught exception (Loader): mlyAction --- > makeml -m68 hpux8 [...stuff deleted...] signature LIST = ... signature VECTOR = ... signature ARRAY = ... signature REAL_ARRAY = ... signature BYTEARRAY = ... signature IO = ... signature BOOL = ... signature STRING = ... signature INTEGER = ... signature BITS = ... signature REAL = ... signature GENERAL = ... [closing boot/perv.sig] uncaught exception (Loader): Ord --- > makeml -m68 hpux8 [...stuff deleted...] structure Core : ... [closing boot/dummy.sml] signature REF = ... signature LIST = ... signature VECTOR = ... signature ARRAY = ... signature REAL_ARRAY = ... signature BYTEARRAY = ... signature IO = ... signature BOOL = ... signature STRING = ... signature INTEGER = ... signature BITS = ... signature REAL = ... signature GENERAL = ... [closing boot/perv.sig] uncaught exception (Loader): Ord --- > makeml -m68 hpux8 [...stuff deleted...] signature CLEANUP = ... signature WEAK = ... signature SUSP = ... signature POLY_CONT = ... signature UNSAFE = ... signature SYSTEM = ... [closing boot/system.sig] signature MATH = ... structure Math : MATH [closing boot/math.sml] [Major collection... 20% used (340948/1682456), 333 msec] uncaught exception (Loader): Ord --- Comments: I cannot tell if this phenomenon is caused by the two fixes I made to sun2hp.el: ;; do-subst -- substitute mnemonics, register names, comment symbols etc. ;; (defun do-subst () [...] (replace-re "\\<jpl" "bpl.w") [...] and the other in: ;; replace-all-label-definitions -- change each of the old label ;; definitions to their new value. ;; (defun replace-all-label-definitions (labels) (while labels (let* ((cur (car labels)) (old-label (label-old-label cur)) (point (label-point cur)) (new-label (label-new-label cur))) (goto-char (- point 2)) (re-search-forward "\\([0-9]+\\):" (point-max) t) (if (not (string-equal (buffer-substring (match-beginning 1) (match-end 1)) old-label)) (error "label <%s> has moved" old-label) (replace-match (concat new-label ":")))) (setq labels (cdr labels)))) [Reppy:] This bug also occurs on the Sun-3 and NeXT machines. It seems to be a general problem with the M68. Status: fixed in 0.84 ---------------------------------------------------------------------- 568. crash on sparc on large compilations Submitter: Pierre Cregut Date: 6/5/92 Version: 0.82 System: sparc, SunOS 4.2 Severity: serious Problem: On large compilations (e.g. compiling the compiler) on sparcs that are shared with other large jobs (e.g. lisp or another sml), the compiler will die with a bus error or illegal instruction or something equally drastic. This is fairly consistent. Comments: Can this be avoided by forcing sml to grap a large memory chunk for the heap and hold onto it. Status: open ---------------------------------------------------------------------- 569. failed type inference with flexible records Submitter: jont@uk.co.harlqn Date: 05-06-92 Version: SML of NJ version number 0.75 System: Sun 4/330 SunOS 4.1.1 Severity: major Problem: Failed type inference with flexible records Code: fun f x = let val y = #1 x val z = #2 x in (y, z, x:('a * 'b)) end; Transcript: - fun f x = let val y = #1 x val z = #2 x in (y, z, x:('a * 'b)) end; fun f x = let val y = #1 x val z = #2 x in (y, z, x:('a * 'b)) end; val f = fn : 'a * 'b -> 'a * 'c * ('a * 'b) - f(1,0); val it = (1,-,(1,0)) : int * 'a * (int * int) - Comments: The type should be 'a * 'b * ('a * 'b) Fix: Better unification I suspect! Status: fixed in 0.85 ---------------------------------------------------------------------- 570. flexrecord equality types Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: 6/8/92 Version: 0.82 System: RISC O/S, MIPS (?) Severity: minor Problem: Flexrecords are always assumed to contain non-equality types when this need not be so. This leads to legal programs being rejected. Code: Consider the following code: fun force_record {x=x, y=y} = 3; fun force_eq x = (x = x); Then, the following function types ok since we close the flexrecord before requiring equality: fun bar (r as {x=x, ...}) = (force_record r; force_eq r); But the following function fails with a "equality type required" error because we attempt to require that the open flexrecord be an equality type: fun foo (r as {x=x, ...}) = (force_eq r; force_record r); Transcript: - use "bug.sml"; (* same code as above *) val force_record = fn : {x:'a,y:'b} -> int val force_eq = fn : ''a -> bool val bar = fn : {x:''a,y:''b} -> bool bug.sml:7.29-7.56 Error: operator and operand don't agree (equality type required) operator domain: ''Z operand: {x:'Y,...} in expression: force_eq r [closing bug.sml] Comments: This problem is due to incorrect code in the type-handling part of the SML/NJ compiler. Fixing this will require changing the definition of types so that flexrecords carry a boolean telling if they are required to have only equality types or not. Unify then needs to be updated to use this information in the proper way. Status: fixed in 0.85 ---------------------------------------------------------------------- 571. no occurs check when instantiating flexrecords Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: 6/8/92 Version: 0.82 System: RISC O/S, MIPS (?) Severity: minor Problem: When flexrecords are instantiated (additional fields added/closed), no occurs check is done. The failure to do this can result in cyclic types and hanging the type checker. Code: The following code hangs the typechecker: fun foo {x=x, y=y, z=(z as {...})} = foo z; Transcript: - fun foo {x=x, y=y, z=(z as {...})} = foo z; [hangs here, using more and more space forever] Comments: The problem is in the unify routine. It needs to do an occurs check whenever it instantiates a flex record. Status: fixed in 0.85 ---------------------------------------------------------------------- 572. unify doesn't update depth for flex record types Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: 6/8/92 Version: 0.82 System: RISC O/S, MIPS (?) Severity: major (* can result in unsoundness *) Problem: The unify routine in the SML/NJ compiler fails to update the depth fields of variables when dealing with flex records. This causes the type checker to generalize types that should not be generalized. Code: Many examples are possible. The simplest I can think of is: fun snd {a,b} = b; fun f (x as {a,...}) = let val u = snd x in u end; Here, snd has type {a:'a,b:'b} -> 'b and acts to extract the b field of an a-b record. So, we start out defining function f. The (x as {a,...}) in the argument list causes x to be bound to the type {a: 'a#1, ...}. [#i means the variable has depth i. I am assuming for this discussion that depths start with 1 and go up 1 for each lambda level.] Now, in the let val u = snd x, we have to unify the type of x with the argument type of snd, namely {a:'c,b:'b}. This results in x being bound to type {a:'a#1, b:'b#2}. Note the error here. Type 'b should have depth 1 not 2 since it is bound at the 1st lambda level (by variable x). However, due to incorrect code in the unifier, this doesn't happen and 'b has type 2. Thus, when we finish typing the function body we get the type 'b#2, which the depth indicates can be safely generalized. Thus, the function body has polymorphic type 'c. This results in f getting type {a:'a, b:'b} -> 'c when it should have the type {a:'a, b:'b} -> 'b. Transcript: - fun snd {a,b} = b; val snd = fn : {a:'a,b:'b} -> 'b - fun f (x as {a,...}) = let val u = snd x in u end; val f = fn : {a:'a,b:'b} -> 'c - f {a=0, b=true}; val it = - : 'a Comments: The problem is in the handling of types by the SML/NJ compiler. Flexrecords need to have a depth associated with them just like normal variables. This is so that you can unify {a:'a#1, ...#1} with {a:'c#3, b:'d#3} and get {a:'a#1, b:'d#1} not {a:'a#1, b:'d#3}. (Note the depth associated with the dots in that example. This is the critical information missing from the current type representation.) Related-bugs: Bug reports #521 from Mark Leone, #533 from Richard O'Neill, and #569 from jont@uk.co.harlqn are all just (less clear) instances of this bug. Status: fixed in 0.85 ---------------------------------------------------------------------- 573. unifier detects spurious cycles with type abbrevs Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: 6/9/92 Version: 0.82 System: RISC O/S, MIPS (?) Severity: minor Problem: The unifier's occurs check sometimes detects a spurious cycle when a type variable is unified with a type abbreviation that stands for that type variable. Code: type 'a ID = 'a; fun f (x:'a) = (x:'a ID); fun g x = g (f x); Transcript: - type 'a ID = 'a; type 'a ID = 'a - fun f (x:'a) = (x:'a ID); val f = fn : 'a -> 'a ID - fun g x = g (f x); std_in:4.1-4.17 Error: pattern and expression in val rec dec don't agree (circularity) pattern: 'Z ID -> 'Y expression: 'Z -> 'Y in declaration: g = (fn x => g (<exp>)) [The above is an incorrect error because 'Z ID = 'Z and hence the two types should unify without problems.] Status: fixed in 0.85 ---------------------------------------------------------------------- 574. redundant patterns in compiler Submitter: John Reppy Date: 6/12/92 Version: 0.83 Severity: minor Problem: The compiler reports the following redundant patterns in 0.83: modules/sigmatch.sml:0.0 Warning: redundant patterns in match (DATACON {name=n1,rep=r1,...},DATACON {rep=r2,...}) => ... --> _ => ... absyn/printabsyn.sml:0.0 Warning: redundant patterns in match FCTB {def=FCTfct {def=def,param=STRvar <pat>,...},fctvar=FCTvar {access=access,name=fname,...}} => ... FCTB {def=VARfct {def=FCTvar <pat>,...},fctvar=FCTvar {access=access,name=fname,...}} => ... --> _ => ... Status: fixed in 0.85 ---------------------------------------------------------------------- 575. line numbers in interactive error messages (same as 552) Submitter: Tim Freeman <tsf@cs.cmu.edu> Date: Sun Jun 14 12:15:40 1992 Version: 0.80 System: Sun 4, mach Severity: minor Problem: The line numbers printed for errors on std_in are erratic. Transcript: % /usr/misc/.sml/bin/sml - aoeiaoei; std_in:3.1-3.8 Error: unbound variable or constructor aoeiaoei - aoeiaoei; std_in:0.0-0.0 Error: unbound variable or constructor aoeiaoei - aoeiaoei = ueoaoeuaoeu; std_in:0.0-0.0 Error: unbound variable or constructor aoeiaoei std_in:4.1-4.11 Error: unbound variable or constructor ueoaoeuaoeu - Comments: In my opinion, the line numbers reported for the above errors should all have been 1, except the last one should have been 2. Status: same as 552 ---------------------------------------------------------------------- 576. pattern matching in interpreter broken Submitter: slind@research.att.com Date: June 14, 1992 Version: 83 System: mips and sparc at least; probably all Severity: major Problem: If System.Control.interp is true, pattern matching is broken. Manifested with list patterns. Transcript: $ sml Standard ML of New Jersey, Version 0.83, June 12, 1992 val it = () : unit - System.Control.interp := true; val it = () : unit - val [_] = [1]; std_in:0.0 Warning: binding not exhaustive _ :: nil = ... uncaught exception Match - System.Control.interp := false; val it = () : unit - val [_] = [1]; std_in:0.0 Warning: binding not exhaustive _ :: nil = ... - ^D $ Comments: There is a bug in the interpreter since version 77 caused by a change in the representation of data constructors. - System.Control.interp:= true; val it = () : unit - val [x] = [1]; std_in:3.1-3.13 Warning: binding not exhaustive x :: nil = ... uncaught exception Match - The reason is that cons is tagged with UNTAGGEDREC 2 and the case UNTAGGEDREC is not treated by the switch. Lal and I have infered that the only thing the switch interpretor had to figure out is whether the constructor is tagged or not. So the only necessary lines to add are: -cregut->diff codegen/interp.sml /usr/local/sml/77/src/codegen/interp.sml 291,296d290 < | f((DATAcon(_,UNTAGGEDREC _),ans)::rest) = < let val rest' = f rest < val ans' = M ans < in fn x => if (U.boxed x) then ans' else rest' x < end < Is it true or do we need something else ? Pierre Status: fixed in 0.86 -------------------------------------------------------------------- 577. use of vectors crashes NeXT Submitter: Richard O'Neill <richard@smaug.questor.wimsey.bc.ca> Date: Thu Jun 18 13:24:53 PDT 1992 Version: 0.75 System: NeXTstation, OS2.1 and NeXTstation Turbo Color, OS 2.2. Severity: Major. Problem: Extensive use of vectors (and probably arrays) when running on NeXTs causes SML to crash with either "Bus Error", "Segmentation Fault", "Illegal instruction" or "EMT trap". The same code, when run on SPARC based Sun machines does not exhibit the same problem. The code below creates a function called 'bug', which takes an integer argument. The larger the argument, the more likely SML is to crash, values like 10000 create an almost immediate crash, values such as 500 sometimes work and sometimes crash SML. (The code is for example purposes only, I don't actually use code as inefficient as this normally! ;o) Code (stored in file "bug.sml"): open Vector fun update(array,index,value) = let fun copy i = if i = index then value else sub(array,i) val size = length array in if index < size then tabulate (size,copy) else raise Vector.Subscript end fun reverse original = let val size = length original fun rev (current,count) = if count < size then let val count' = count + 1 val current' = update(current, count, sub(original, size-count')) in rev (current', count') end else current in rev (original,0) end fun bug n = reverse (tabulate (n, fn x => x)) Transcript: NeXT-Mach% sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "bug.sml"; [opening bug.sml] open Vector val update = fn : 'a vector * int * 'a -> 'a vector val reverse = fn : 'a vector -> 'a vector val bug = fn : int -> int vector [closing bug.sml] val it = () : unit - bug 500; val it = - : int vector - bug 500; Bus error NeXT-Mach% NeXT-Mach% sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "bug.sml"; [opening bug.sml] open Vector val update = fn : 'a vector * int * 'a -> 'a vector val reverse = fn : 'a vector -> 'a vector val bug = fn : int -> int vector [closing bug.sml] val it = () : unit - bug 5000; EMT trap NeXT-Mach% NeXT-Mach% sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "bug.sml"; [opening bug.sml] open Vector val update = fn : 'a vector * int * 'a -> 'a vector val reverse = fn : 'a vector -> 'a vector val bug = fn : int -> int vector [closing bug.sml] val it = () : unit - bug 5000; Bus error Comments: It gives an idea how 'wild' the crash is since the latter two cases in the transcript should be identical, and aren't. I suspect it is some kind of memory allocation bug, but who knows.... Comment: [dbm, 10/29/92] Couldn't reproduce this on a Sun 3 with 0.91. Either the bug is cured or it is NeXT specific. Status: fixed in 0.92 ---------------------------------------------------------------------- 578. chatting (in runtime system) doesn't flush stdout Submitter: Mark Leone (mleone@cs.cmu.edu) Date: June 24, 1992 Version: 80 System: all Severity: minor Problem: chatting() doesn't flush stdout Code: Transcript: Comments: GC messages (and other diagnostic compiler output) sometimes appear before things that have already been printed to stdout (e.g. when redirecting batch compiler output to a log file). This can make it hard to debug the compiler. Fix: Add "fflush(stdout)" to chatting() in runtime/run.c Status: not a bug (inaccurate report according to awa) ---------------------------------------------------------------------- 579. Lexing an illegal token can lead to infinite loop Submitter: Andrew Tolmach (apt@research.att.com) Date: 30 June Version: 0.83 System: MIPS and SPARC Severity: Problem: Lexing an illegal token can lead to infinite loop. Code: Typing an arbitrary control character (such as CTRL/A), followed by return, sends system into an infinite loop. Transcript: - ^A std_in:0.0 Error: illegal token ... (infinite loop) ... Comments: (1) Looping doesn't occur if illegal token is followed by a complete legal phrase, e.g., ^A1; (2) Loop can be interrupted with CTRL/C. (3) Didn't occur in 0.82. Fix: Exception handler in ml.lex.sml uses Reject instead of Internal.Reject when Internal is not open, thus producing a handler for all exceptions. Change Reject to Internal.Reject in lexgen. Status: fixed in 0.84 ---------------------------------------------------------------------- 580. System.Compile, System.Env broken in 0.83 Submitter: Emden R. Gansner erg@ulysses.att.com Date: 3 July 1992 Version: 0.83 System: Sparc 2, SunOS 4.1 Severity: major Problem: Support for separate compilation is broken Code: fun bug () = let open System.Compile System.Env val staticPerv = staticPart(!pervasiveEnvRef) val ins = open_string "signature T = sig end" val source = makeSource("<string>", 1, ins, false, std_out) val (static, _) = compile(source,staticPerv) in changeLvars static end Transcript: Standard ML of New Jersey, Version 0.83, June 12, 1992 val it = () : unit - use "bug.sml"; val bug = fn : unit -> System.Compile.staticUnit [closing bug.sml] val it = () : unit - bug(); Error: Compiler bug: CompileUnit 2 - Status: fixed in 0.86 ---------------------------------------------------------------------- 581. line numbers in error and warning messages Submitter: Andrew Appel Date: 7/3/92 Version: 0.83 Severity: serious Problem: Many of the error and warning messages have line numbers of 0.0. Comments: Something wrong in the use of markabsyn. Status: fixed in 0.88 ---------------------------------------------------------------------- 582. interaction of open declarations and eval_stream Submitter: Andrew Tolmach (apt@research.att.com) Date: 7 July 92 Version: 0.83 System: MIPS riscos Severity: minor Problem: If an open declaration is evaluated by System.Compile.eval_stream, the resulting first-class environment is inconsistent: the static environment contains the elements of the opened structure, but the structure itself is not included in the dynamic environment. Subsequent attempts to look up these elements in the first-class environment trigger IntMapF exceptions. Transcript: Standard ML of New Jersey, Version 0.83, June 12, 1992 val it = () : unit - open System.Compile System.Env System.Symbol; open Compile Env Symbol - structure Fred = struct val a = 10 end; structure Fred : sig val a : int end - val e = eval_stream(open_string "open Fred", = layerEnv(!topLevelEnvRef,!pervasiveEnvRef)); open Fred [closing <instream>] val e = prim? : environment - val e' = layerEnv(e,!pervasiveEnvRef); val e' = prim? : environment - eval_stream(open_string "a",e'); [closing <instream>] uncaught exception IntmapF - Fix: (suggested by Tolmach) A top-level open should create a new structure entry in the dynamic environment, and paths for entries in the static environment should be adjusted to point at this new entry. Fix: (implemented in 0.91) A top-level open causes all the runtime components of the structures opened to be rebound in the top-level environment. Status: fixed in 0.91 ---------------------------------------------------------------------- 583. catalogEnv raises Match exception Submitter: Andrew Tolmach (apt@research.att.com) Date: 7 July 92 Version: 0.83 System: Mips riscos Severity: minor Problem: Executing System.Env.catalogEnv(staticPart (!pervasiveEnvRef)) provokes a Match exception. Comment: Problem is evidently with modules/moduleutil.sml:sortEnvBindings.binderGt, which contains an incomplete match. Perhaps TAB binding entries need to be included? Status: fixed in 0.85 ---------------------------------------------------------------------- 584. infinite loop in cpsopt Submitter: John Reppy (jhr@research.att.com) Date: 7/10/92 Version: 0.84 Severity: major Problem: The following program causes an infinite loop in cpsopt (I assume that this is another case of infinite loop unrolling): Code: fun foo () = let fun loop () = loop () in loop () end; Status: fixed in 0.86 ---------------------------------------------------------------------- 585. wrong type for notb in perv.sig Submitter: Nick Haines (Nick_Haines@VOILA.VENARI.CS.CMU.EDU) Date: 7/10/92 Version: 0.84 Severity: minor Problem: In boot/perv.sig, the type of `notb' is given as int * int -> int not as int -> int as it should be (and as boot/perv.sml has it). Fix: change the type in perv.sig Status: fixed in 0.86 ---------------------------------------------------------------------- 586. uncaught Match in interpreter Submitter: John Reppy (jhr@research.att.com) Date: July 10, 1992 Version: 0.77 and later System: any Severity: minor Problem: an uncaught exception Match in the interpreter Code: System.Control.interp := true; datatype t = Z | S of t; fn (S _) => 0; Transcript: Standard ML of New Jersey, Version 0.77, February 24, 1992 Arrays have changed; see Release Notes val it = () : unit - datatype t = Z | S of t; System.Control.interp := true; fn (S _) => 0; datatype t con S : t -> t con Z : t val it = () : unit std_in:2.57-2.69 Warning: match not exhaustive S _ => ... uncaught exception Match - Comments: Mark Lillibridge tracked this down to codegen/interp.sml; specifically, the function "f" in the case SWITCH(e,_, l as (DATAcon _, _)::_, d) => ... The problem seems to be a result of the changes in the datatype representation. Is this the same as bug #576? Bug # 591 is another instance of this Status: fixed in 0.86 ---------------------------------------------------------------------- 587. Compiler bug: ModuleUtil: Instantiate:getSigPos.2<Argument> Submitter: Olivier Nora Date: 7/14/92 Version: 0.84 Severity: major Problem: Following code produces compiler bug: ModuleUtil: Instantiate:getSigPos.2<Argument> Code: signature SEQUENCE = sig exception LoopingError type 'a sequence val read : '1a sequence -> ('1a * '1a sequence) option val append : '1a list * '1a sequence -> '1a sequence val add_to : '1a sequence -> '1a sequence -> unit val app : ('2a -> '2b) sequence -> '2a sequence -> '2b sequence val value : '1a -> '1a sequence val empty_sequence : unit -> '1a sequence end signature SEMANTIC_VALUE = sig type 'a semantic_type type semantic_value type 'a sequence exception SemanticValueError of string val add_semantic_value : semantic_value -> semantic_value -> unit val cast_from : 'a semantic_type -> semantic_value -> 'a sequence val cast_to : 'a semantic_type -> 'a sequence -> semantic_value val void_semantic_value : semantic_value end funsig MK_SEMANTIC_VALUE (Sequence : SEQUENCE) = SEMANTIC_VALUE functor MkWhole (functor MkSemanticValue : MK_SEMANTIC_VALUE) = struct end Comment: [Cregut] The bug can be obtained by the simple following code: signature A=sig end signature B=sig functor f():A end; and comes from the fact that A is declared before so contains no arguments. The fix is a 3 lines changed in extern.sml that ask the function not to worry if the argument is not there. It should be in .85 Status: fixed in 0.85 ---------------------------------------------------------------------- 588. wrong printing of flex records with no fields Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: July 14, 1992 Version: 0.83 Severity: minor Problem: The abstract syntax printing routines print out flex records with no fields wrong. I.e., as "{,...}" instead of "{...}". Code: (fn {...} => ()) 3; Transcript: - (fn {...} => ()) 3; std_in:18.1-18.18 Error: operator and operand don't agree (type mismatch) operator domain: {...} operand: int in expression: ((fn {,...} => ())) 3 ^^^^-------------------- note error Comments: same as bug #468 which was mislabeled Status: fixed in 0.85 ---------------------------------------------------------------------- 589. occurs check with nonstrict type abbreviations Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: July 14, 1992 Version: 0.83 Severity: minor Problem: The occurs check is done wrong in the presense of non-strict type abbreviations. Code: type 'a CON = int; fun foo (x:'a) = (3:'a CON); fun bar x = bar (foo x); Transcript: - type 'a CON = int; type 'a CON = int - fun foo (x:'a) = (3:'a CON); val foo = fn : 'a -> 'a CON - fun bar x = bar (foo x); [type checker hangs at this point] Status: fixed in 0.85 ---------------------------------------------------------------------- 590. Some user type variable names are handled incorrectly. Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: July 14, 1992 Version: 0.83 Severity: minor Problem: Some user type variable names are handled incorrectly. Code: val x : '_1abcd = 3; Transcript: - val x : '_1abcd = 3; std_in:0.0-0.0 Error: pattern and expression in val dec don't agree (type mismatch) pattern: '1_1abcU expression: int in declaration: x : '1_1abcU = 3 ^^^^------------------- note no 'd' on end! Comment: Note that this kind of type variable name is no longer legal as of 0.85. Status: fixed in 0.85 ---------------------------------------------------------------------- 591. uncaught Match evaluating fn expressions. Submitter: Elsa Gunter Date: 7/15/92 Version: 0.84 Severity: major Problem: Match exception raised when evaluating innocuous "fn" expressions. This was in a version of 0.84 in which eXene was loaded. Transcript: - fn (th :: _) => [th] | nil => nil; uncaught exception Match - fn (SOME x) => [x] = | NONE => []; uncaught exception Match Comment: does not occur in plain 0.84 Confirmed to be an instance of bug #586 Status: open ---------------------------------------------------------------------- 592. unhelpful error messages for record type mismatches Submitter: thomas yan, tyan@cs.cornell.edu Date: 7/17/92 Version: <= .85 Severity: minor, but annoying Problem: unhelpful error messages for record type mismatches Code: val {e:int, g:int, i:int, k:int option, m:int, p:int, ...} = {e=0, g=0, j=0, k=[0], n=0, p=0, r=0, t=0, w=0, x=0, z=0} (* and similar variations *) Transcript: - val {e:int, g:int, i:int, k:int option, m:int, p:int, ...} = {e=0, g=0, j=0, k=[0], n=0, p=0, r=0, t=0, w=0, x=0, z=0}; std_in:0.0-331.117 Error: pattern and expression in val dec don't agree (record labels) pattern: {e:int,g:int,i:int,k:int option,m:int,p:int,...} expression: {e:int,g:int,j:int,k:int list,n:int,p:int,r:int,t:int,w:int,x:int,z:int} in declaration: {e=e : int,g=g : int,i=i : int,k=k : int option,m=m : int,p=p : int,...} = {e=0,g=0,j=0,k=0 :: nil,n=0,p=0,r=0,t=0,w=0,x=0,z=0} - val {e:int, g:int, i:int, k:int option, m:int, p:int} = {e=0, g=0, j=0, k=[0], n=0, p=0}; std_in:0.0-331.87 Error: pattern and expression in val dec don't agree (tycon mismatch) pattern: {e:int,g:int,i:int,k:int option,m:int,p:int} expression: {e:int,g:int,j:int,k:int list,n:int,p:int} in declaration: {e=e : int,g=g : int,i=i : int,k=k : int option,m=m : int,p=p : int} = {e=0,g=0,j=0,k=0 :: nil,n=0,p=0} Comments: the error messages should indicate which labels are a) ok, b) extra/mispelled, c) missing. also, (and this is a problem in general with type error messages), the field type mismatches should be highlighted, as just "tycon mismatch" gives one no idea where the mismatch is. Fix: use some kind of field by field comparison of the pattern and expression (a 2-column format, while verbose, might work well), perhaps first listing all fields that match, then listing all labels with mismatched types, then extra labels in the expression, then (possibly even for flex records) omitted labels. Status: open ---------------------------------------------------------------------- 593. Compiler bug from bad overload declaration Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: 7/17/92 Version: 0.83 System: Sparc Severity: minor Problem: When values supplied in an overload declaration fail to meet the spec given, a compiler bug sometimes occurs. Code: fun baz [x] = x + 1; overload quux : ('a -> 'a) as tl and baz; Transcript: - fun baz [x] = x + 1; std_in:0.0 Warning: match not exhaustive x :: nil => ... val baz = fn : int list -> int - overload quux : ('a -> 'a) as tl and baz; Error: Compiler bug: matchScheme: bad tyvar 0 Status: fixed in 0.93c ---------------------------------------------------------------------- 594. "val _ = =;" now giving a different (wrong) error (same as 549) Submitter: Mark Lillibridge (mdl@cs.cmu.edu) Date: 7/17/92 Version: 0.83 System: Sparc Severity: minor Problem: "val _ = =;" now giving a different (wrong) error Code: val _ = =; Transcript: - val _ = =; std_in:7.9 Error: nonfix identifier required Error: Compiler bug: elabVB Comment: This bug report is an addeneum to bug report #549. That bug reported that a non-handled Match exception occured on this program. This bug report is to report that that no longer happens in 0.83. Instead, a "elabVB" compiler bug occurs. Still a bug though. Status: same as 549 ---------------------------------------------------------------------- 595. uncaught exception UnboundTable compiling bogus signature Submitter: John Reppy Date: July 22, 1992 Version: 0.85 System: Sun 4/75 Severity: minor Problem: uncaught exception UnboundTable in compiler Code: signature JGRAPH = sig structure IO end functor JGraph (IO : IO) : JGRAPH = struct end Transcript: Standard ML of New Jersey, Version 0.85, July 17, 1992 val it = () : unit - use "bug.sml"; bug.sml:3.5-3.13 Error: syntax error: replacing STRUCTURE with EQTYPE bug.sml:1.1-8.5 Error: unmatched type spec: IO [closing bug.sml] uncaught exception UnboundTable - Comments: If you type the code into the top-level loop, you get a different kind of syntax error, and the bug doesn't occur. Status: fixed in 0.89 ---------------------------------------------------------------------- 596. bad line number info in error messages Submitter: Andrew Appel Date: 7/24/92 Version: 0.86 Severity: major Problem: Many error messages say line "0.0-0.0". Status: fixed in 0.88 ---------------------------------------------------------------------- 597. Compiler bug: errors in cps/generic/extract Submitter: Magnus Carlsson <magnus@cs.chalmers.se> Date: 7/26/92 Version: 0.75 System: Sun-4 Severity: major Problem: Following code causes Compiler bug: errors in cps/generic/extract. Code: datatype 'a fcont = Fcont of 'a fcont cont | Thrown of 'a; case callcc Fcont of Fcont k => throw k (Thrown 5) | Thrown i => i; Transcript: animal> smlc Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "callcc-error.ml"; [opening callcc-error.ml] datatype 'a fcont con Fcont : 'a fcont cont -> 'a fcont con Thrown : 'a -> 'a fcont Error: Compiler bug: errors in cps/generic/extract [closing callcc-error.ml] - Status: fixed in 0.89 ---------------------------------------------------------------------- 598. Compiler bug: applyTyfun: not enough arguments Submitter: Andrew Appel Date: 7/27/92 Version: 0.86 Severity: minor Problem: Compiler bug after incorrect datatype/withtype declaration. Code: datatype 'a t = A of u withtype 'a u = 'a list Transcript: foo.sml:0.0 Error: type constructor u has the wrong number of arguments: 0 Error: Compiler bug: applyTyfun: not enough arguments Comment: [mdl] Turned out to be another bug in the module system where a bad tycon was returned in spite of an error being detected. Fix is to change so that ERRORtyc is returned on error. The diffs to fix it follow. I tested the change on the 86 sources and it seems to work fine. Fix: diff moduleutil.sml.86 moduleutil.sml: ------------------ cut here ------------------ 524c524 < fun checkArity(tycon, arity,err) = --- > fun checkArity(tycon, arity,err,result) = 526c526 < of ERRORtyc => () --- > of ERRORtyc => result 529,531c529,532 < then err COMPLAIN ("type constructor "^(Symbol.name(tycName(tycon)))^ < " has the wrong number of arguments: "^makestring arity) < else () --- > then (err COMPLAIN ("type constructor "^(Symbol.name(tycName(tycon)))^ > " has the wrong number of arguments: "^makestring arity); > ERRORtyc) > else result 537,538c538,539 < (checkArity(spec,arity,err); < RELtyc{name=name,pos=(relpos,pos)}) --- > checkArity(spec,arity,err, > RELtyc{name=name,pos=(relpos,pos)}) 540,541c541,542 < (checkArity(spec,arity,err); < RELtyc{name=name,pos=pos}) --- > checkArity(spec,arity,err, > RELtyc{name=name,pos=pos}) 544c545 < | (TYCbind tyc,_,_) => (checkArity(tyc,arity,err); tyc) --- > | (TYCbind tyc,_,_) => checkArity(tyc,arity,err,tyc) Status: fixed in 0.88 ---------------------------------------------------------------------- 599. symbolic path names are reversed in error messages. Submitter: Andrew Appel Date: 7/27/92 Version: 0.86 Severity: minor Problem: Symbolic path names are reversed in error messages. What should be "MipsInstrSet.instruction", is instruction.MipsInstrSet (etc.) Transcript: mips/mips.sml:0.0 Error: Inconsistent arities in sharing type instruction.MipsIn strSet = instruction.C.<Parameter> : instruction.MipsInstrSet has arity 1 and in struction.C.<Parameter> has arity 0. mips/mips.sml:0.0 Error: Inconsistent arities in sharing type sdi.MipsInstrSet = sdi.C.<Parameter> : sdi.MipsInstrSet has arity 1 and sdi.C.<Parameter> has arit Status: fixed in 0.89 ---------------------------------------------------------------------- 600. Core dump running sourcegroup 2.1 Submitter: Amy Felty Date: 7/28/92 Version: 0.86 System: Sparc, SunOS 4.1 Severity: major Problem: Core dump running sourcegroup 2.1 Code: SMLTool.targetNamer := SourceAction.sysBinary; System.Control.Print.signatures := 0; System.Control.indexing := true; structure SG = SourceGroup; structure SA = SourceAction; structure FL = FileList; fun smlFiles dirs = FL.extensionsOnly ["fun", "sig", "sml"] (FL.inDir (false, dirs)); fun mlyaccFiles dirs = FL.extensionsOnly ["lex", "grm"] (FL.inDir (false, dirs)); val mlyaccGroup = SG.create [SG.Sources (FL.inFile ["mlyacc/base/base.files"])]; Transcript: - lutece:working> sml-sg Standard ML of New Jersey, Version 0.86, July 22, 1992 with SourceGroup 2.1 built on Fri Jul 24 10:48:49 EDT 1992 val it = () : unit - use "build-elp.sml"; val it = () : unit val it = () : unit val it = () : unit structure SG : SOURCEGROUP structure SA : SOURCEACTION structure FL : FILELIST val smlFiles = fn : string list -> string list val mlyaccFiles = fn : string list -> string list Segmentation fault lutece:working> Status: fixed in 0.87 ---------------------------------------------------------------------- 601. bad implementation of Assembly.A.logb Submitter: John Reppy (jhr@research.att.com) Date: 7/29/92 Version: 0.75-0.85 (probably earlier versions too) System: SPARC Severity: minor Problem: The implementation of logb in runtime/SPARC.prim.s doesn't work for 0.0 Code: (System.Unsafe.Assembly.A.logb 0.0) Transcript: Standard ML of New Jersey, Version 0.86, July 22, 1992 val it = () : unit - (System.Unsafe.Assembly.A.logb 0.0); val it = uncaught exception Boxity Fix: "beq 1f" should be "beq 2f" Status: fixed in 0.87 ---------------------------------------------------------------------- 602. uncaught exception UnboundTable using System.Env.describe Submitter: Dave MacQueen Date: 9/29/92 Version: 0.85 Severity: major Problem: Invoking System.Env.describe on topLevelEnv with structure symbol "System" yields uncaught exception UnboundTable Transcript: Standard ML of New Jersey, Version 0.85, July 17, 1992 val it = () : unit - System.Env.describe (System.Env.staticPart (!System.Env.topLevelEnvRef)) (System.Symbol.strSymbol "System"); uncaught exception UnboundTable - Comment: System is in Pervasives, not topLevelEnv, but describe should catch the exception and give a report. Status: fixed in 0.89 (Cregut) ---------------------------------------------------------------------- 603. System.Symbol.makestring gives eroneous answer Submitter: cregut Date: 7/29/92 Version: .83 -> .86 System: all Severity: minor Problem: System.Symbol.makestring gives eroneous answer Code: Transcript: - open System.Symbol; open Symbol - makestring(sigSymbol "s"); val it = "TYC$s" : string Comments: bad order of namespaces Fix: change makestring in env.sml Test File: let open System.Symbol in if (makestring(valSymbol "s")^makestring(tycSymbol "s")^ makestring(sigSymbol "s")^makestring(strSymbol "s")^ makestring(fctSymbol "s")^makestring(fixSymbol "s")) = "VAL$sTYC$sSIG$sSTR$sFCT$sFIX$s" then "System.Symbol.makestring seems O.K." else "Verify the behaviour of System.Symbol.makestring" handle _ => "System.Symbol.makestring has a major bug" end Status: fixed in 0.87 ---------------------------------------------------------------------- 604. blast_read/blast_write broken Submitter: Emden R. Gansner erg@ulysses.att.com Date: 30 July 1992 Version: 0.86 System: Sparc 2, SunOS 4.1 Severity: major Problem: blast_read/blast_write is broken Code: (* The following function writes a value, then reads it back in * and compares them. In 0.86, the values are not equal. * If one attempts to print v', the system hangs, causing a * core dump on interrupt. * You can replace 'int list' with your favorite eqtype *) fun btest v = let val ofd = open_out "dump" val bwrite : outstream * int list -> int = System.Unsafe.blast_write val bread : instream * int -> int list = System.Unsafe.blast_read val sz = bwrite(ofd,v) val _ = close_out ofd val ifd = open_in "dump" val v' = bread(ifd,sz) in close_in ifd; if v = v' then print "v = v'\n" else print "print v <> v'\n" end Transcript: Standard ML of New Jersey, Version 0.86, July 22, 1992 val it = () : unit - use "btest.sml"; val btest = fn : int list -> unit [closing btest.sml] val it = () : unit - btest []; [Major collection...abandoned] print v <> v' val it = () : unit - btest [1,2]; [Major collection...abandoned] print v <> v' val it = () : unit - Comments: Does this have anything to do with bug 548 being fixed? Fix: [Appel] at the beginning of ml_blast_out in cfuns.c, insert the following line after "blast_fd = REC_SEL..." msp->ml_arg = arg; Then do a makeml -noclean and things ought to work better. Status: fixed in 0.87 ---------------------------------------------------------------------- 605. whose bug? Submitter: Charles Krasic cckrasic@plg.waterloo.edu Date: July 31, 1992 Version: 0.75 System: Sparc, SunOS 4.1.2 Severity: critical Problem: file compiles OK with batch compiler, but runtime/run fails with "uncaught exception (Loader): Syntax" Comments: I am working on the source code of NJSML itself. I have made some fairly significant changes so it would be a non-trivial amount of work for me to give you all the code necessary to run NJSML and reproduce my problem. I have isolated my problem to 1 line of code in the source code which is will briefly summarize here. The file that contains the code in question is at the end of this message. This code is part of my modified type checker. Roughly, it is called prior to the 0.75 typechecker (there are many changes...) This seems to be a very nasty bug to me. It should be noted that, while I am changing the compiler, I am compiling my changed version with the stock 0.75 version of the batch compiler. My changes are confined entirely to the front end of the compiler (nothing after typechecking). Some of the things I tried: The offending section of code is: 1. (case var of 2. (VALvar{constraints,...}) => 3. (ConstraintsStack.push constraints; 4. constructList := (constraints :: (!constructList)); 5. expType(env,exp,err,loc); 6. ConstraintsStack.pop()) 7. | _ => (ErrorMsg.impossible "MakeImplicitsPass.Pass2.valrecType")) If lines 3,4 and 6 are removed (and 5 has the semicolon removed), it will build OK. Alternatively, if line 5 is removed, it also will build OK. Of course, either of those things doesn't do what I want it to do. I have tried many variations on the above code but could not get any to work. Status: not a bug (bug was in his own code) ---------------------------------------------------------------------- 606. Allocating space for saved FP registers is awkward Submitter: Mark Leone (mleone@cs.cmu.edu) Date: July 31, 1992 Version: 0.82 System: i386 Severity: Necessary change for i386 runtime Problem: Allocating space for saved FP registers is awkward Code: none Transcript: none Comments: In runtime/signal.c, in make_ml_sigh_arg(), floating point registers are saved as follows: #if (NSAVED_FPREGS > 0) savefpregs (msp); fpregs = PTR_CtoML(msp->ml_allocptr + sizeof(long)); msp->ml_allocptr += (NSAVED_FPREGS*2 + 1) * sizeof(long); #else ... This code assumes that savefpregs only needs NSAVED_FPREGS*2 + 1 words. This assumption fails on the 386, since the entire FP coprocessor state must be saved, not just the registers. Fix: A better approach is for savefpregs() to update the allocptr itself and return a pointer to the saved state: #if (NSAVED_FPREGS > 0) fpregs = savefpregs (msp); #else ... Comment: [jhr] A better fix might be introducing a machine dependent constant for the fp-save area size. Also, savefpregs should probably get the save area pointer as its argument, since this would simplify the assembly code a bit. Status: open ---------------------------------------------------------------------- 607. weak typing Submitter: John Greiner <John.Greiner@WAGOSH.FOX.CS.CMU.EDU> Date: 8/4/92 Version: 0.86 Severity: major Problem: Weak typing error allows failure of type security. Transcript: - fn x => let val a = ref nil in (let val b = a in b := [true]; hd (!b) + 1; (fn z => z) end) () end; val it = fn : 'a -> unit Fix: This can be fixed by replacing "absd-abs" by "max(0,absd-abs)" in basics/typesutil.sml. Status: fixed in 0.89 ---------------------------------------------------------------------- 608. minor error in runtime Submitter: David Tarditi Date: 8/4/92 Version: 0.85 Severity: minor Problem: In version 0.85, line 114: run.c, there's a function call of the form: init_externlist(msp) but you'll see in cfuns.c that init_externlist takes no arguments. Status: fixed in 0.89 ---------------------------------------------------------------------- 609. include syntax Submitter: Larry Paulson <Larry.Paulson@cl.cam.ac.uk> Date: 7/31/92 Version: 0.75 Severity: minor Problem: Standard ML of New Jersey, Version 75, seems to reject the syntax include SIGID1 ... SIGIDn (See the definition of Standard ML, page 13.) Status: fixed in 0.90 ---------------------------------------------------------------------- 610. changeLvars broken Submitter: Gene Rollins Date: 8/5/92 Version: 0.87 Severity: major (for separate compilation) Problem: There is a compiler bug in SML/NJ 0.85 and 0.87 that is not present in 0.80. I tracked it down to this: the function changeLvars when applied to a staticUnit sometimes eliminates bindings to fixity symbols. So, if you try to read a compiled binary file, and then compile a file that uses symbols defined in the binary file, you sometimes get an error such as this: a.sig:1.15-1.19 Error: FIRST undefined (parser) If the symbol is really undefined you also get this message: a.sig:1.15-1.19 Error: unbound signature: FIRST This happens on pmax_mach and sun4_mach machines. I found that once you have a binary file that this bug happens with, it is repeatable. But, not all binary files tickle this bug. Transcript: - System.system "cat first.sig"; signature FIRST = sig val x:int end - val perv = !System.Env.pervasiveEnvRef; val perv = prim? : environment - val se = System.Env.staticPart perv; val se = prim? : staticEnv - val (staticUnit, codeUnit) = SepComp.compileSource ("first.sig", se); [closing first.sig] val staticUnit = {boundLvars=[],staticEnv=prim?} : System.Compile.staticUnit val codeUnit = prim? : codeUnit - val delta = System.Compile.execute ((staticUnit, codeUnit), perv); signature FIRST <other binding> val delta = prim? : environment - appSE (findName "FIRST") delta; (* catalogEnv; filter for symbols "FIRST" *) FIRST fixity information of a module component FIRST signature val it = () : unit - val staticUnit2 = System.Compile.changeLvars staticUnit; val staticUnit2 = {boundLvars=[],staticEnv=prim?} : System.Compile.staticUnit - val delta2 = System.Compile.execute ((staticUnit2, codeUnit), perv); signature FIRST val delta2 = prim? : environment - appSE (findName "FIRST") delta2; FIRST signature val it = () : unit - Fix: adjust for new representation of fixity bindings? Status: fixed in 0.91 (dbm) ---------------------------------------------------------------------- 611. batch compiler doesn't like local structure declarations Submitter: Mark Leone (mleone@cs.cmu.edu) Date: August 5, 1992 Version: 0.82 System: all Severity: very minor Problem: batch compiler doesn't like local structure declarations Code: (* From bug report #278 *) local structure Internal = struct val x=1 val y=2 end in structure First : sig val x : int end = Internal structure Second : sig val y : int end = Internal end Transcript: Standard ML of New Jersey, Version 82, June 1, 1992 (batch compiler) [Compiling tmp.sml] Error: signature, functor, or structure expected [closing tmp.sml] Comments: This seems to be the same problem exhibited by the interactive top-level in bug report #278 (which has been fixed). Status: open ---------------------------------------------------------------------- 612. bad lambda depth calculated in type checker Submitter: Mark Lillbridge (mdl@cs.cmu.edu) Date: August 5, 1992 Version: 0.87 System: Sparc Severity: major Problem: Lambda depth is miscalculated in some cases causing the compiler to core dump Code: fun id x = x; (fn y => id (let val u = y in u end)) 1 2; Transcript: - fun id x = x; val id = fn : 'a -> 'a - (fn y => id (let val u = y in u end)) 1 2; Bus error (core dumped) Comments: The code in typesutil.sml that calculates lamdepth is wrong. In cases like this, lamdepth can actually decrease instead of being monotonically increasing. (Here, lamdepth is 1 at the fn y => but 0 at the let.) Status: fixed in 0.89 ---------------------------------------------------------------------- 613. Compiler bug message on occurence of typevar in signature Submitter: Kees van Schaik <kees@diku.dk> Date: August 7 1992 Version: Version 75 System: Sun 4 Sparc station running SunOS Release 4.1.1 Severity: minor Problem: Compiler bug message on occurence of typevar in signature Code: signature BuggySignature = sig exception IllegalException of '_a ref end Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 The Edinburgh SML Library Make is now pre-loaded. val it = () : unit - signature BuggySignature = sig exception IllegalException of '_a ref end; signature BuggySignature = sig exception IllegalException of Error: Compiler bug: domain Comments: The signature is not a legal one since it is not allowed to use type variables in exception declarations in signatures. A somewhat more informative way of telling that would be nice (mostly to people who did not know/realise that their code was not legal when triggering the bug, who will most probably the only ones triggering it), but the bug does not cause any serious problems. Comments: [dbm] Now generates an error message when signature is elaborated. Status: fixed in 0.91 (dbm) ---------------------------------------------------------------------- 614. high-order-functor thinning-in Submitter: Zhong Shao (zsh@cs.princeton.edu) Date: August 6, 1992 Version: 0.86 System: mipsb/riscos Severity: critical Problem: high-order-functor thinning-in Code: signature SIG = sig val e : real end funsig PROD (structure M : SIG structure N : SIG) = SIG structure S = struct val e = 100.0 end structure P = struct val e = 0.0 end functor Square(structure X : SIG functor Prod : PROD) : SIG = Prod(structure M = S structure N = X) functor F(structure N : SIG) = struct val e = (N.e * N.e) end structure A = Square(structure X = P functor Prod = F); A.e; Transcript: ..................... - A.e; val it = 10000.0 : real Comments: A.e should be 0.0 instead. The problem is that when F is applied to (structure M=S structure N=P) in the body of functor Square, the argument is not thinned against the parameter signature of the functor F. Status: fixed in 0.89 ---------------------------------------------------------------------- 615. System.Symbol.makestring has incomplete implementation Submitter: Andrew Tolmach (apt@research.att.com) Date: 10 Aug 92 Version: 0.85 through 0.88 System: mips riscos Severity: minor Problem: Can't apply System.Symbol.makestring to pervasive environment. Code: - let open System.Env System.Symbol in map makestring (catalogEnv (staticPart(!pervasiveEnvRef))) end; Transcript: above code causes Compiler bug: Symbol.makestring Fix: Add TABspace case to Env.symbolToString (?) Status: fixed in 0.89 ---------------------------------------------------------------------- 616. overloading versus user-bound type variable Submitter: Lars Birkedal <birkedal@diku.dk> Date: 8/12/92 Version: 0.87 (and earlier) Severity: minor Problem: I assume you resolve arithmetic overloading in NJSml by binding the operators, such as +, to a generel type-scheme, such as \forall 'a. 'a *'a -> 'a, where the type-variables are marked as overloaded, and then elaborates as usual with the exception that overloaded type variables are not allowed to be quantified. (Some examples I've run indicates this.) The following example seems to indicate that you allow unification of overloaded type variables with explicit type variables and when unifying marks the explicit type variables as overloaded. This mark prohibits quantification of the explicit type variable at its scoping declaration, hence violating rule 17 in the Definition. My question is --- why allow unification of overloaded typevariables with explict type variables at all?; since quantification is not allowed, overlaoding cannot be resolved this way (as in let val f = fn x => x + x in f 2 end, which elaborates), so the only other way is to unify the explicit type variable with int or real, which is not allowed, hence overloading cannot be resolved this way either. So what do you gain? Transcript: - let val f = fn (x: 'a) => x + x in f 2 end; std_in:1.5-1.31 Error: explicit type variable cannot be generalized at its scoping declaration: 'a std_in:1.29 Error: overloaded variable "+" cannot be resolved Comment: [dbm] The type variables of the type scheme of an overloaded variable are "marked as overloaded" when an instance of the type scheme is created for a particular applied occurence of the variable. This marking is accomplished by a book-keeping device -- each type metavariable substituted for a bound variable of the scheme is given a "depth" of zero. The depth attribute is used to determine whether a metavariable can be generalized at a val binding, and a depth of zero will prevent these metavariables (or metavariables in types substituted for them) from ever being generalized. When one of these metavariables is unified with a "user-bound" type variable like the 'a in your example, the depth of the metavariable is propagated to the user-bound variable, which in this case prevents the user-bound variable from being generalized at the appropriate place. This looks like a bug -- in fact, I think that the user-bound variable should probably not have a depth attribute at all. Status: not a bug (but alternate handling might be better) ---------------------------------------------------------------------- 617. interpreter fails with "no default in interp" Submitter: Andrew Tolmach (apt@research.att.com) Date: 12 Aug 92 Version: 0.87 System: mips riscos Severity: major Problem: On a variety of programs, the interpreter fails with "no default in interp". Code: System.Control.interp := true; use "/usr/local/sml/benchmarks/leroy.sml"; (* the standard knuth-bendix benchmark *) Transcript: signature KB = sig datatype ordering con Equal : ordering con Greater : ordering con NotGE : ordering datatype term con Term : string * term list -> term con Var : int -> term val doit : unit -> unit val kb_complete : (term * term -> bool) -> (int * (int * (term * term))) list -> ('a * ('b * (term * term))) list -> unit val lex_ext : (term * term -> ordering) -> term * term -> ordering val rpo : (string -> string -> ordering) -> ((term * term -> ordering) -> term * term -> ordering) -> term * term -> ordering end /usr/local/sml/benchmarks/leroy.sml:603.1-608.22 Warning: match not exhaustive "U" => ... "*" => ... "I" => ... "B" => ... "C" => ... "A" => ... Error: Compiler bug: no default in interp [closing /usr/local/sml/benchmarks/leroy.sml] Comments: Failure to track changes in data representations? If the debugger is built using makeml -i, this bug occurs the first time a usedbg_live is tried. Status: fixed in 0.90 ---------------------------------------------------------------------- 618. LOOKUP FAILS, Compiler bug: 110 in CPSgen Submitter: Dave MacQueen Date: 8/15/92 Version: 0.87 System: Sparc, Mips Severity: critical Code: (* bug618.sml *) signature S0 = sig exception Error of string (* string arg necessary *) end functor F (X : S0) = struct open X fun extend_one (i,v,r) j = if i = j then v else (r j) (* necessary *) fun extend_env _ = raise Error "foo" end structure A : S0 = struct exception Error of string end structure B = F(A) Transcript: skye$ sml Standard ML of New Jersey, Version 0.87, July 31, 1992 val it = () : unit - use "bug618.sml"; LOOKUP FAILS in close(FIX 2373 ) on 2310 in environment: 2370 2368 2451 2448 2449 2450 2369/callee 2451 - 2448 2449 2450 Error: Compiler bug: 110 in CPSgen [closing bug618.sml] - use "bug618.sml"; Illegal instruction(coredump) skye$ Status: fixed in 0.89 ---------------------------------------------------------------------- 619. Compiler bug: Escapemap on xxxx Submitter: Dave MacQueen Date: 8/15/92 Version: 0.87 System: Sparc, Mips Severity: critical Code: (* bug619.sml *) signature SIG = sig exception Error of string end functor F (X : SIG) = struct open X datatype Exp = APP of Exp * (Exp list) datatype Val = FUNC of Val list -> (Val -> unit) -> unit fun extend_one (i,v,r) j = if i = j then v else (r j) fun extend_env([],[],r) = r | extend_env(i::is,v::vs,r) = extend_env(is,vs,extend_one(i,v,r)) | extend_env _ = raise Error "mismatching environment extension" fun meaning (APP(e,es)) r k = meaning e r (fn (FUNC f) => meaninglis es r (fn vs => f vs k)) and meaninglis [] r k = k [] | meaninglis (e :: es) r k = meaning e r (fn v => meaninglis es r (fn vs => k (v :: vs))) end structure A : SIG = struct exception Error of string end structure B = F(A) (* necessary *) Transcript: - skye$ sml Standard ML of New Jersey, Version 0.87, July 31, 1992 val it = () : unit - use "bug619.sml"; Error: Compiler bug: Escapemap on 2423 [closing bug619.sml] - Comment: probably closely related to bug 618. Minor simplifications of the code produce a version of bug 618. Status: fixed in 0.89 ---------------------------------------------------------------------- 620. higher-order functor causes Compiler bug Submitter: Dave MacQueen Date: 8/15/92 Version: 0.87 Severity: major Problem: Higher order functor definition fails with "Compiler bug: abstractfct:tyconSeries1: param tycon not found" Code: signature SIG = sig datatype d = D of unit (* the "of unit" is necessary for bug *) end functor Twice(functor F(A:SIG):SIG) = struct functor TwiceF(A: SIG) = F(F(A)) end Transcript: - use "bug620.sml"; Error: Compiler bug: abstractfct:tyconSeries1: param tycon not found [closing bug620.sml] Status: fixed in 0.89 ---------------------------------------------------------------------- 621. polymorphic equality not eliminated as often as it should be Submitter: aitken@cs.cornell.edu (William E. Aitken) Date: Aug 13, 1992 Version: 0.87 (also 0.88b) System: sun4 sunos Severity: minor Problem: polymorphic equality not eliminated as often as it should be Code: val eq = (op =) val eq1 : int * int -> bool = (op =) val eq2 = (op =) : int * int -> bool Transcript: (Script started on Thu Aug 13 11:46:13 1992) ai $ sml Standard ML of New Jersey, Version 0.87, July 31, 1992 val it = () : unit - System.Control.CG.printit := true; val it = () : unit - (* this should be implemented as poly-eq *) = val eq = op =; After convert: 2316(2314,2315) = 2317(2313,2318) = 2319(2320) = 2318((I)0) 2313((I)99,2319) 2317(2314,2315) . . . val eq = - : ''a * ''a -> bool - (* this should be implemented as integer equality, but isn't *) = val eq1 : int * int -> bool = (op =) ; After convert: 2346(2344,2345) = 2347(2343,2348) = 2349(2350) = 2348((I)0) 2343((I)99,2349) 2347(2344,2345) . . . val eq1 = - : int * int -> bool - - (* this should be implemented as integer equality, and is *) = val eq2 = (op =) : int * int -> bool; After convert: 2376(2374,2375) = 2377(2373,2378) = 2379(2380) = 2382(2381,2383) = 2381.0 -> 2384 2381.1 -> 2385 if ieql(2384,2385) [2388] then 2383((I)1) else 2383((I)0) {2382} -> 2389 2378(2389) 2373((I)99,2379) 2377(2374,2375) . . . val eq2 = fn : int * int -> bool (script done on Thu Aug 13 11:47:39 1992) Comments: eq1 implements the equality check as a call to polymorphic equality, while eq2 inline expands the equality for the type int. This is particularly obnoxious since, at least to me, the declaration of eq1 looks prettier. Status: fixed in 0.89 ---------------------------------------------------------------------- 622. Bus error on DECstation 5000/200 Submitter: Urban Engberg <urban@daimi.aau.dk> Date: 8/18/92 Version: 0.75-0.80 System: DECstation 5000/200 and 5000/240 Severity: major Problem: I have been using SML of NJ for a couple of years, mostly for writing compiler-related tools. The tool I am currently working on contains about 7000 lines of sml-code, including the code produced by sml-lex and -yacc. The relatively large size of the program seems essential to my problem to be described. When compiling the code, by reading in the files with "use", the sml system once in a while crashes with messages such as pid 22613 (tlac.orig) was killed on an unaligned access, at pc 0x100a3550 Bus error (core dumped) The problem has been specific to running on DECstations 5000/200 and 5000/240 (at least) but occurs on all the machines of this kind that I have tried. I have been able to bear over with the problems for some time, without trying to find the error, as I would just have to restart the compilation at the right point a couple of times. Lately, however, the problem has started showing up more and more often when I execute the binary image I create with the library-construct "exportFn". As my code has been growing, I have now got a ratio of well-functioning runs to ones crashing of about 1:10! Thus it is beginning to be a very big problem. [added 8/19/92] The problem occurs at random. But running a compilation which takes about five seconds will currently produce the crash nine times out of ten. I am running Ultrix version 4.2A (Apr 92), which I suppose is one of the newest. I remember having had problems all the time since I began using DEC machines though, since March 91. You are quite right in that `unaligned access' errors seems to indicate some sort of Ultrix bug. Comments: [George] This brings back memories of when I was bringing up the new MIPS code generator. The regression tester specifically, would run just fine on a MIPSEB but would crash once in a while in a non-deterministic manner on a MIPSEL. The error message was identical - unaligned access, at pc ... At the time, we concluded that this was an operating system related problem, and not the fault of the generated code. Unfortunately, I did not persist in getting to the root of the problem. I am not able to reproduce the error as the regression tester being used is gone!! My suggestion would be to try a post v 0.82 release that had even less reliance on the operating system - i.e., any trapless gc version. Followup: [Urban Engberg, 8/24/92] It has been making me curious that the errors lately doesn't seem to show up in other programs than my compiler (where it with earlier sml versions has been a problem with many programs, and also when compiling the compiler). So with a good guess, I tried removing some calls I had to `IO.execute'. This made a crucial difference; the compiler now runs without any problems. To help finding the error, it should be noted that the compiler works fine *with* the `IO.execute' commands, when run from within an interactive sml session. I have tried to reproduce the error in a smaller program, but without success. The calls to `IO.execute' looked as follows: val (datestream, dummy) = IO.execute ("/bin/csh", ["-cfb", "/bin/date +\"%a %h %d%H:%M 19%y\""]) val date = input (datestream, 21) before (close_in datestream; close_out dummy) Status: fixed in 0.89 ---------------------------------------------------------------------- 623. wildcard is equivalent to a serie of wildcards (see also 629) Submitter: cregut Date: 20/8/92 Version: .88 System: all Severity: minor/major Problem: wildcard is equivalent to a serie of wildcards Code: fun foo x 0 = x | foo _ = 0; (* this failed in pre-0.88 versions *) Transcript: val foo = fn : int -> int -> int Status: fixed in 0.90 ---------------------------------------------------------------------- 624. System.Env.filterEnv causes Compiler bug: copystat. Submitter: Gene Rollins Date: 8/21/92 Version: 0.88 Severity: major Problem: System.Env.filterEnv causes compiler bug: copystat. Code: ==== env.sml ==== structure TestEnv = struct fun printEnv (e:System.Env.environment) = app (fn s=> (print ((System.Symbol.makestring s) ^ "\n"))) (System.Env.catalogEnv (System.Env.staticPart e)) val TestStructure = System.Symbol.strSymbol "Test"; fun test() = (use "test.sml"; printEnv (!System.Env.topLevelEnvRef); print "----------\n"; printEnv(System.Env.filterEnv(!System.Env.topLevelEnvRef,[TestStructure]))) end ==== test.sml ==== structure Test = struct val x = 4 end Transcript: Standard ML of New Jersey, Version 0.88, August 14, 1992 - use "env.sml"; structure TestEnv : sig val TestStructure : symbol val printEnv : environment -> unit val test : unit -> unit end - TestEnv.test(); structure Test : sig val x : int end [closing test.sml] STRTAB$Test STRTAB$TestEnv STR$Test STR$TestEnv VAL$it ---------- Error: Compiler bug: copystat - Status: fixed in 0.89 (Cregut) ---------------------------------------------------------------------- 625. Runbind exception still being raised. Submitter: Gene Rollins, Andrew Appel Date: 8/21/92 Version: 0.88 Severity: major Problem: Runbind exception still being raised. Status: fixed in 0.91 (not verified) ---------------------------------------------------------------------- 626. extra spaces in SPARC.prim.s Submitter: Gene Rollins Date: 8/21/92 Version: 0.88 System: SPARC Severity: Problem: It appears that our assembler can't handle the extra spaces given in several of the #defines in the original file SPARC.prim.s.0. The new SPARC.prim.s works fine. Here are the differences. They are all within the first 55 lines. Fix: % diff SPARC.prim.s.0 SPARC.prim.s 26c26 < #define exncont g7 /* exception handler (ml_exncont) */ --- > #define exncont g7 /* exception handler (ml_exncont) */ 29,35c29,35 < #define limit g4 /* heap limit pointer (ml_limitptr)*/ < #define stdarg i0 /* standard argument (ml_arg) */ < #define stdcont i1 /* standard continuation (ml_cont) */ < #define stdclos i2 /* standard closure (ml_clos) */ < #define baseptr i3 /* base code pointer (ml_roots[]) */ < #define varptr i5 /* var pointer (ml_varptr) */ < #define stdlink g1 --- > #define limit g4 /* heap limit pointer (ml_limitptr)*/ > #define stdarg i0 /* standard argument (ml_arg) */ > #define stdcont i1 /* standard continuation (ml_cont) */ > #define stdclos i2 /* standard closure (ml_clos) */ > #define baseptr i3 /* base code pointer (ml_roots[]) */ > #define varptr i5 /* var pointer (ml_varptr) */ > #define stdlink g1 49,53c49,53 < #define tmp1 o2 < #define tmp2 o3 < #define tmp3 o4 < #define tmp4 o5 /* also used to pass register mask to g.c. */ < #define gclink o7 /* link register for return from g.c. (ml_pc) */ --- > #define tmp1 o2 > #define tmp2 o3 > #define tmp3 o4 > #define tmp4 o5 /* also used to pass register mask to g.c. */ > #define gclink o7 /* link register for return from g.c. (ml_pc) */ Status: Fixed in 0.89 ---------------------------------------------------------------------- 627. blast-writing objects outside the heap leads to failure Submitter: David Tarditi Date: 8/21/92 Version: 0.88 Severity: major Problem: blast-write fails when given an object that is outside the heap. The following program (for version 0.75, shareable) demonstrates this. You'll have to change the program slightly to run it in the latest version of the compiler, since the type of blast_read has changed. Code: structure blast = struct val s = System.version val outblast = fn () => let val outfd = open_out "testblast" in (System.Unsafe.blast_write (outfd, s); close_out outfd) end val inblast = fn () => let val infd = open_in "testblast" val res : string = System.Unsafe.blast_read infd val _ = close_in infd in (print "Got back: "; print res; print " : from testblast\n") end val _ = outblast () val _ = inblast () end Transcript: - use "/usr/dtarditi/tmp"; [opening /usr/dtarditi/tmp] [Major collection...abandoned] Got back: : from testblast structure blast : sig val inblast : unit -> unit val outblast : unit -> unit val s : string end [closing /usr/dtarditi/tmp] val it = () : unit Comments: In the shareable version of the compiler, where the code for the compiler is palced outside the heap, the string System.version ends up outside the heap. Fix: The solution is to add a check to the code for blast-write, I think, for the case where the object being blasted out is a pointer that is outside the heap. [Tarditi, 8/21/92:] I remember there was some problem about import not working across different compiled versions of the same compiler. For example, I think import files created with a shareable version of the compiler caused the nonshared version to crash. I've realized what the problem is, and it is worth noting down for future reference. The basic problem is that blast_write isn't fully generally, and only works with a particular executable. If you blast-write an object which contains pointers that are outside the heap, the garbage collector just copies the pointers as though they were integers. The problem is that with different executables, the objects outside the heap may not exist at all, may be different (that is, the pointer points to junk), or they may be at a different address. Think about what happens when you blast-write a function. The function will most likely contain objects from the pervasive environment in its closure. Suppose one of those objects from the pervasive environment is a closure. It will contain a code pointer. If the compiler is shareable version, the code pointer will be outside the heap. Now, if we try to read blast_read this function into a nonshareable version of the compiler, the code pointer will be junk! Note that you'll have this problem even if only the runtime has been changed across executables. This will change the address of code for the assembly language primitives, and the addresses of ML objects allocated as static C data structures. A possible solution to add a level of indirection between objects in the runtime system and blast-written objects. (1) give every possible ML object in the runtime system a unique name (2) when blast-writing an object, translate ML objects outside the heap to their unique names (3) when blast-reading an object, translate from the unique names back to the ML objects. We could hack something up to deal with the code strings for the pervasives being either in the heap or text segment. We'd have to put a limitation that you can only blast-read/blast-write objects outside the heap which are "registered" (i.e. you can't blast-write things like the code for the compiler). At least things could fail gracefully instead of crashing. Status: fixed in 0.89 ---------------------------------------------------------------------- 628. System.Env.filterEnv broken (accidental duplicate of 624) ---------------------------------------------------------------------- 629. fun declaration syntax (see 623) Submitter: aitken@cs.cornell.edu (William E. Aitken) Date: Sat Aug 29 1992 Version: 0.88 (back to 0.83 -- worked in 0.82) System: Sun 4m/670 MP Sparc, SunOS Release 4.1.2 Severity: minor Problem: function declarations made using `fun' may arbitrarily mix clauses in which the formal parameters are curried and clauses in which they are uncurried. Note that if they are uncurried, the formal pattern must be of n-tuple type. That is, it may be a variable pattern or a wildcard pattern or a tuple pattern of the appropriate arity. Code: fun foo 1 x = 17 | foo (a, b) = a + b fun bar (1, x) = 17 | bar a b = a - b fun splat a b = 4 | splat x = 5 Transcript: % sml Standard ML of New Jersey, Version 0.88, August 14, 1992 val it = () : unit - fun foo 1 x = 17 = | foo (a, b) = a + b; val foo = fn : int -> int -> int - fun bar (1, x) = 17 = | bar a b = a - b; val bar = fn : int * int -> int - fun splat a b = 4 = | splat x = 5; std_in:5.17-6.15 Warning: redundant patterns in match (a,b) => ... x => ... val splat = fn : 'a -> 'b -> int - ^D % Comments: There are two function declarations in translate/tempexpn.sml that (accidentally) exploit this bug. They are the last two functions of the structure. In the first case, the second argument needs to be uncurried, in the second case, the final clause needs a second wildcard pattern. Similarly, the function labBranchOff in mips/mipsinstr.sml, needs a second wildcard pattern in its final clause's formal parameters. The problem occurs because no explicit test is ever made to ensure that clauses have the same number of argument patterns. In elaborating a function declaration, the compiler produces something of the form fn x1 => ... => fn xn => case (x1, ..., xn) of p1 => e1 . . . pm => em x1, ..., xn are distinct new variables. ei is the expression of the ith clause. n is the number of patterns in the *first* clause If the ith clause has r > 1 patterns (pi1, ..., pir), pi is the the pattern (pi1, ..., pir). If the ith clause has only one pattern, pi is that pattern. The type checker will detect most mis-matches between numbers of arguments --- e.g., fun foo a b c = 4 | foo a b = 5; std_in:7.17-7.31 Error: rules don't agree (tycon mismatch) expected: 'Z * 'Y * 'X -> int found: 'W * 'V -> int rule: (a,b) => 5 but will not catch mis-matches between appropriately typed single patterns and multiple patterns. Fix: Add a check that the number of formal parameters agrees in each clause. Rewriting checkFB in parse/astutils.sml as follows should work, the compiler compiles itself to a fixpoint with it installed, but I have *not* tested the resulting code very thoroughly. (Note that translate/tempexpn.sml and mips/mipsinstr.sml need to be fixed too, as described above). fun checkFB(clauses as ({name,pats,...}:rawclause)::rest, err) = let val patslen = length pats in if exists (fn {name=n,...} => not(Symbol.eq(n,name))) rest then err COMPLAIN "clauses don't all have same function-name" else if exists (fn {pats=p,...} => length p <> patslen) rest then err COMPLAIN "clauses don't all have same number of patterns" else (); clauses end | checkFB _ = ErrorMsg.impossible "CoreLang.checkFB" if calculating the length is too expensive here, using the function fun len1 [x] = true | len1 _ = false will suffice, at the expense of less good error reporting. Status: same as 623 ---------------------------------------------------------------------- 630. smallest number literal in patterns (same as 507) Submitter: aitken@cs.cornell.edu (William E. Aitken) Date: Sat Aug 29 1992 Version: 0.88 System: Sun 4m/670 MP Sparc, SunOS Release 4.1.2 Severity: minor Problem: the special constant denoting the smallest member of the type int (~1073741824) causes compilation failure if it appears in patterns. It is legal in expressions. Code: fun foo ~1073741824 = 5 | foo x = 3 Transcript: % sml Standard ML of New Jersey, Version 0.88, August 14, 1992 val it = () : unit - ~1073741824; val it = ~1073741824 : int - fun foo ~1073741824 = 5 | foo x = 3; Error: Compiler bug: Overflow in cps/generic.sml - ~1073741824; val it = uncaught exception Boxity - ~1073741824; val it = ~1073741824 : int 1073741824; std_in:2.1-2.10 Error: integer too large - ^D % Comments: If I've already submitted this bug, sorry. Status: open ---------------------------------------------------------------------- 631. PrintVal can't print a value of the Ast type Submitter: cregut Date: 8/29/92 Version: from .86 System: sparc mips.. Severity: Problem: PrintVal can't print a value of the Ast type Code: (* int.sml *) structure interface = struct local open System.Compile System.Env in fun ast name = let val f = open_in name val source = makeSource (name,0,f,false,std_out) val (ast : System.Ast.dec,_) = parse(source,staticPart (!pervasiveEnvRef)) in ast end end end Transcript: - use "int.sml"; structure interface : sig val ast : string -> System.Ast.dec end [closing int.sml] val it = () : unit - interface.ast "int.sml"; val it = SeqDec [MarkDec (Error: Compiler bug: PrintVal.switch: none of the data cons matched - Comments: The AST type is built in parse/ast.sml but another version is in system.sig and perv.sml so that the user can access it. It is not a problem of consistency of defs (no changes with 85). Fix: make sure ast.sml is compiled with newconreps having the same value that will be default for the user. That is, put "^newconreps !ast.sml ^newconreps" in the "all" file. Status: fixed in 0.89 ---------------------------------------------------------------------- 632. minimal or maximal integer literals in patterns cause compiler bug Submitter: aitken@cs.cornell.edu (William E. Aitken) Date: August 30, 1992 Version: 0.88, also 0.75 System: SunOS Release 4.1.2, Sun 4m/670 MP Sparc Severity: major Problem: Integer patterns larger than 2^29-1 or smaller than ~2^29 trigger a compiler bug. Code: fun foo 0x20000000 = true | foo x = false; Transcript: Standard ML of New Jersey, Version 0.88, August 14, 1992 val it = () : unit - fun foo 0x20000000 = 5 ; std_in:2.1-2.22 Warning: match not exhaustive 536870912 => ... Error: Compiler bug: Overflow in cps/generic.sml - 12; val it = uncaught exception Boxity - fun foo ~0x20000000 = 5 ; std_in:0.0-0.0 Warning: match not exhaustive ~536870912 => ... val foo = fn : int -> int - fun foo ~0x20000001 = 5; std_in:2.1-2.23 Warning: match not exhaustive ~536870913 => ... Error: Compiler bug: Overflow in cps/generic.sml - Comments: This is just a generalization of a bug reported yesterday. Status: same as 507 ---------------------------------------------------------------------- 633. space leak Submitter: John Reppy Date: 1/9/92 Version: 0.88 Severity: major Problem: The old space leak in capture/escape seems to have reappeared. I ran my test on versions 0.75-0.88, and here is a summary of the results: version space leak? 75 no 76 no 77 yes 78 yes 79 yes 80 yes 81 no 82 no 83 no 84 yes 85 yes 86 yes 87 yes 88 yes Note that the two rounds of contract before eta were eliminated in version 0.84. As a reminder, the simple example of this problem is the function select. Code: local open System.Unsafe.PolyCont in fun select x = capture (fn k => let val return = escape k in return (x ()) end) end; which is called in the following loop: fun loop () = select loop Comments: This should be constant space! Status: fixed (again!) in 0.90 ---------------------------------------------------------------------- 634. Uncaught expception NotDirectory Submitter: Zhong Shao (zsh@cs.princeton.edu) Date: Sept. 4, 1992 Version: 0.88 System: mipsb/riscos and mipsl/ultrix Severity: major Problem: Uncaught expception NotDirectory Code: (************************************************************************** * THIS IS THE FILE getwd.sml --------- Modified from SourceGroup * * version 2.2 tools/sourcegroup/local/System/getwd.sml * **************************************************************************) structure GetWorkingDirectory :sig val getwd :unit -> string end = struct fun withInOutStreams (inS :instream, outS :outstream) (action :instream * outstream -> 'a -> 'b) (argument:'a) :'b = let val result = action (inS, outS) argument handle exn => (close_in inS; close_out outS; raise exn) in close_out outS; close_in inS; result end val SYS_wait = 84 fun waitForProcess () = (while (((System.Unsafe.CInterface.syscall (SYS_wait, System.Unsafe.cast 0)) handle System.Unsafe.CInterface.SysError _ => 0) > 0) do ()) fun firstLine (program:string, args :string list) = let fun strip_newline str = let val len = size str in if len > 0 then substring (str, 0, len - 1) else str end fun first_line (inS,outS) () = strip_newline (input_line inS) val result = withInOutStreams (execute (program, args)) first_line () in waitForProcess(); result end fun getwd () = firstLine ("/bin/pwd", []) end val _ = (let val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd val cwd = GetWorkingDirectory.getwd() val _ = System.Directory.cd cwd in print "\n \n This is correct! \n \n" end) handle _ => (print "\n\n This is wrong, Why exceptions? \n\n") Transcript: - use "getwd.sml"; This is wrong, Why exceptions? structure GetWorkingDirectory : sig val getwd : unit -> string end [closing /u/zsh/tcps/work/new/bug/tt.sml] val it = () : unit - Comments: "Uncaught exception NotDirectory" happened RANDOMLY(50%) when doing "val cwd = GetWorkingDirectory.getwd(); System.Directory.cd cwd;" This is why I did ten runs of it in the above script. I suspect the getwd.sml in SourceGroup is coded in an incompatible way with the version 88's Directory.cd function in perv.sml (or runtime/cfuns.c), since the above bug did not occur in 87. This bug occurs (sometimes,say one out of two times) when making smlsg using version88. ** This is probably another example of bug #651 (JHR, 10/6/92) ** Status: fixed ---------------------------------------------------------------------- 635. byteArray.update and ByteArray.sub raise Ord Submitter: Robert Cooper (rcbc@cs.cornell.edu) Date: Sept 10, 1992 Version: 0.75 (broken in 0.89) System: any Severity: minor Problem: byteArray.update and ByteArray.sub raise Ord instead of Subscript Transcript: Standard ML of New Jersey, Version 0.89, September 4, 1992 val it = () : unit - open ByteArray; open ByteArray - val a = array(2, 0); val a = - : bytearray - update (a, 2, 100); uncaught exception Ord - a sub 2; uncaught exception Ord Comments: The inline operators are incorrectly defined. Status: fixed in 0.90 ---------------------------------------------------------------------- 636. Vector patterns don't work at top level Submitter: Dave MacQueen Date: 9/10/92 Version: 0.88 Severity: major Problem: Vector patterns don't work at top level Transcript: Standard ML of New Jersey, Version 0.89, September 4, 1992 val it = () : unit - val v = #[1,2,3]; val v = #[1,2,3] : int vector - val #[a,b,c] = v; std_in:5.1-5.16 Warning: binding not exhaustive #[a,b,c] = ... - a; uncaught exception IntmapF - let val #[a,b,c] = v in a end; std_in:0.0-0.0 Warning: binding not exhaustive #[a,b,c] = ... val it = 1 : int Status: fixed in 0.90 ---------------------------------------------------------------------- 637. Compiler bug printing signatures with polymorphic exceptions (same as 613) Submitter: Gene Rollins Date: 9/10/92 Version: 0.88? Severity: minor Problem: The Compiler reports a compiler bug when trying to print signatures that contain polymorphic exceptions. This happens with both 0.75 and 0.80 versions on both sun4 and decstation machines running mach. Code: Transcript: - signature SEQUENCE = sig exception no_next of 'a end; signature SEQUENCE = sig exception no_next of Error: Compiler bug: domain Comments: If we set: System.Control.Print.signatures := 0; the compiler compiles the signature fine, and does not report the compiler bug. [DBM:] Polymorphic exception specifications in signatures are (or should be) illegal, so these should cause some error message. Status: same as 613 ---------------------------------------------------------------------- 638. subnormal numbers Submitter: Appel Date: 9/15/92 Version: 0.89 System: Sparc Severity: minor Problem: The "ln" function does not expect subnormal numbers, and gives wrong answers. Other functions may have similar problems. Code: Transcript: val x = 1.0E~160; val x = 1.0E~160 : real - x * x; val it = 9.99988867182683E~321 : real - ln it; val it = ~4.05753556581235 : real - Comments: Fix: Status: fixed in 0.90 ---------------------------------------------------------------------- 639. multiple compiler compilations on sparc fail Submitter: Pierre Cregut Date: 9/15/92 Version: 0.89 System: SunOS 4.1, SPARC 2, 64MB Severity: major Problem: When multiple compilations of the ML compiler are launched on a single sparc 2, some of them fail with "Bus error" or "Segmentation fault". Transcript: I have done the experiment but forgot it... so here is the result of launching 3 smlc (.89) on skye One is Ok and has finished... another: > [closing elaborate/normalize.sml] > [Compiling modules/moduleutil.sml] > structure ModuleUtil : ... > > [Major collection... 7% used (1403140/20038536), 1040 msec] > Bus error and the last > signature GENERAL = ... > [closing boot/perv.sig] > [Loading boot/system.sig] > > [Increasing heap to 24114k] > Segmentation fault who died very quickly !! Comments: Why did it asked for such a swap space suddenly: it is completely ridiculous at that point... Status: open ---------------------------------------------------------------------- 640. flakiness of System.Env (particularly filterEnv) Submitter: Sanjiva Prasad <sanjiva@ecrc.de> Date: 9/16/92 Version: 0.88 Severity: major Problem: Perhaps someone in your group has already discovered and fixed these bugs in v88. We had pulled over a copy of v88 to experiment with the new environment features you had advertised (with the intention of trying out an mini interpreter that does not maintain the application environment, but evaluates a syntax tree in a given environment). I mucked around a bit, trying to create some small environments by making type, structure, functor and value declarations, then using map, some list operations like rev and some auxiliary functions, and (from System.Env) catalogEnv, topLevelEnvRef, staticPart and filterEnv. Unfortunately, I kept getting Compiler Bug messages when I used filterEnv (I organized my program carefully enough to isolate the occurrence of these to the use of filterEnv). The ugly part of the story is that although repeating the evaluation resulted in the same bug message or exception being raised, there was no pattern to it. For instance, filtering out an environment from the top-level environment using a list of seven symbols -- obtained from applying staticPart and then catalogEnv -- resulted in a compiler bug message "compstat" (I think it was that). With a different list (again obtained using list operations, catalogEnv, staticPart and topLevelEnvRef), I got uncaught exception IntmapF, and then with another list (this time built using string-to-symbol functions in System.Symbol), I got another compiler bug (I can't recall which). In all cases, it is when trying to use filterEnv. Comment: [dbm] can't reproduce Status: open ---------------------------------------------------------------------- 641. higher-order functors give Compiler bug: PrintVal.switch: none ... Submitter: Sanjiva Prasad <sanjiva@ecrc.de> Date: 9/16/92 Version: 0.88 Severity: major Problem: Use of higher-order functors results in Compiler bug when a value of a datatype is printed. Transcript: - signature SIG1 = sig type t type u val x:t val y:u end; signature SIG1 = sig type t type u val x : t val y : u end - structure A:SIG1 = struct type t=int type u=bool val x=5 val y=true end; structure A : SIG1 - - signature SIG2 = sig = functor Foo(X:SIG1) : sig val z : A.t val w: X.t end = end; (* This was to test if the restriction on what names may be used -- relevant for separate compilation -- was enforced in v88 *) signature SIG2 = sig functor Foo : <sig> end - structure B : SIG2 = struct functor Foo(X:SIG1) = struct val z = A.x + 1 val w = X.x = type foo = bool = end = end; structure B : SIG2 (* This was to test if signature contraints of SIG2 were propagated down to the body of the functor. Pleasantly, it is *) - open B; open B - structure C = Foo(A); structure C : sig val z : A.t val w : A.t end - structure D :SIG1 = struct type t = bool type u = int val x = false val y = 7 end; structure D : SIG1 - structure E = Foo(D); structure E : sig val z : A.t val w : D.t end - C.w; val it = 1 : A.t (* should have been equal to A.x = 5 !!!!! *) - A.x; val it = 5 : A.t - C.z; val it = 6 : A.t (* rightly so *) - E.z; val it = 6 : A.t (* again rightly so *) - E.w; (* should have been false *) val it = Error: Compiler bug: PrintVal.switch: none of the datacons matched Status: fixed in 0.89 ---------------------------------------------------------------------- 642. Sourcegroup 2.1 dependency analysis fails (see also bug 649) Submitter: Amy Felty, felty@research.att.com Date: 17 Sept 92 Version: 0.90a System: sun4 sparc Severity: major Problem: SG2.1 compiles, but doesn't execute propery. The last version that I know of where it works properly is 0.87. In a call to SourceGroup.make, one of the arguments is the name of the top-level functor (ElpSymtab in this example). It should then be able to determine all the necessary files to compile and build the structures. Instead, it replies with: % structure ElpSymtab undefined Code: I have put a tar file in ~felty/lp-sml/SGbug.tar. It is not very large, but contains files in several subdirectories. (It is a very small piece of the Lambda Prolog code.) Transcript: I'm including a transcript of the execution in 0.90a with the bug, followed by a transcript of the working version in 0.87. ------------------------ transcript for SML 0.90a ------------------------ % /usr/local/sml/bin/sparc/sml-sg.90a Standard ML of New Jersey, Version 0.90a September 16, 1992 with SourceGroup 2.1 built on Wed Sep 16 20:11:34 EDT 1992 val it = () : unit - use "build.sml"; val it = () : unit val it = () : unit val it = () : unit structure SG : SOURCEGROUP structure SA : SOURCEACTION structure FL : FILELIST val smlFiles = fn : string list -> string list val mlyaccFiles = fn : string list -> string list hash/Hash.sig hash/Hash.sml hash/link-hash.sml val hashGroup = 1 : ?.group sys/hasher.sml sys/link-sys.sml sys/location.sml sys/profile.sml sys/sys.sig sys/sys_newjersey.fun sys/time.sml val sysGroup = 3 : ?.group val libraries = [1,3] : ?.group list [closing group-libraries.sml] val it = () : unit lam/basic.fun lam/basic.sig lam/term.fun lam/term.sig lam/naming.fun lam/naming.sig val lamGroup = 5 : ?.group elp/elp_symtabs.fun elp/elp_symtabs.sig elp/link-elp.sml val elpGroup = 7 : ?.group val makeElp = fn : unit -> unit [closing group.sml] val it = () : unit val make = fn : unit -> unit % structure ElpSymtab undefined val it = () : unit [closing build.sml] val it = () : unit ----------------------- transcript for SML 0.87 ----------------------- % /usr/local/sml/bin/sparc/sml-sg Standard ML of New Jersey, Version 0.87, July 31, 1992 with SourceGroup 2.1 built on Mon Aug 3 14:02:28 EDT 1992 val it = () : unit - use "build.sml"; val it = () : unit val it = () : unit val it = () : unit structure SG : SOURCEGROUP structure SA : SOURCEACTION structure FL : FILELIST val smlFiles = fn : string list -> string list val mlyaccFiles = fn : string list -> string list hash/Hash.sig hash/Hash.sml hash/link-hash.sml val hashGroup = 1 : ?.group sys/hasher.sml sys/link-sys.sml sys/location.sml sys/profile.sml sys/sys.sig sys/sys_newjersey.fun sys/time.sml val sysGroup = 3 : ?.group val libraries = [1,3] : ?.group list [closing group-libraries.sml] val it = () : unit lam/basic.fun lam/basic.sig lam/term.fun lam/term.sig lam/naming.fun lam/naming.sig val lamGroup = 5 : ?.group elp/elp_symtabs.fun elp/elp_symtabs.sig elp/link-elp.sml val elpGroup = 7 : ?.group val makeElp = fn : unit -> unit [closing group.sml] val it = () : unit val make = fn : unit -> unit [reading sys/time.sml] [closing sys/time.sml] [writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/time.sml.bin] signature TIME <other binding> functor Time <other binding> [reading sys/sys.sig] [closing sys/sys.sig] [writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/sys.sig.bin] signature SYS <other binding> [reading sys/sys_newjersey.fun] [closing sys/sys_newjersey.fun] [writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/sys_newjersey.fun.bin] functor NewJersey <other binding> [reading sys/location.sml] [closing sys/location.sml] [writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/location.sml.bin] signature LOCATION <other binding> functor Location <other binding> [reading sys/hasher.sml] [closing sys/hasher.sml] [writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/hasher.sml.bin] functor Hasher <other binding> signature HASHER <other binding> [reading sys/link-sys.sml] [closing sys/link-sys.sml] [writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/link-sys.sml.bin] <other binding> <other binding> <other binding> <other binding> <other binding> <other binding> <other binding> <other binding> [reading lam/term.sig] [closing lam/term.sig] [writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/term.sig.bin] signature TERM <other binding> [reading lam/term.fun] [closing lam/term.fun] [writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/term.fun.bin] functor Term <other binding> [reading lam/naming.sig] [closing lam/naming.sig] [writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/naming.sig.bin] signature NAMING <other binding> [reading lam/basic.sig] [closing lam/basic.sig] [writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/basic.sig.bin] signature BASIC <other binding> [reading lam/naming.fun] [closing lam/naming.fun] [writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/naming.fun.bin] functor Naming <other binding> [reading lam/basic.fun] [closing lam/basic.fun] [writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/basic.fun.bin] functor Basic <other binding> [reading hash/Hash.sig] [closing hash/Hash.sig] [writing /shadow/12/people/felty/lp-sml/SGtest/hash/.@sys/Hash.sig.bin] signature HASH <other binding> [reading hash/Hash.sml] [closing hash/Hash.sml] [writing /shadow/12/people/felty/lp-sml/SGtest/hash/.@sys/Hash.sml.bin] functor HashFun <other binding> [reading hash/link-hash.sml] [closing hash/link-hash.sml] [writing /shadow/12/people/felty/lp-sml/SGtest/hash/.@sys/link-hash.sml.bin] <other binding> <other binding> [reading elp/elp_symtabs.sig] [closing elp/elp_symtabs.sig] [writing /shadow/12/people/felty/lp-sml/SGtest/elp/.@sys/elp_symtabs.sig.bin] signature ELPSYMTAB <other binding> [reading elp/elp_symtabs.fun] [closing elp/elp_symtabs.fun] [writing /shadow/12/people/felty/lp-sml/SGtest/elp/.@sys/elp_symtabs.fun.bin] functor ElpSymtab <other binding> [reading elp/link-elp.sml] [closing elp/link-elp.sml] [writing /shadow/12/people/felty/lp-sml/SGtest/elp/.@sys/link-elp.sml.bin] <other binding> <other binding> <other binding> <other binding> <other binding> <other binding> <other binding> <other binding> val it = () : unit [closing build.sml] val it = () : unit Comments: Lal and John suggest that a regression test be made for source groups. Status: fixed in 0.91 (Shao) ---------------------------------------------------------------------- 643. building smld produces Compiler bug: DebugError: ... Submitter: John Reppy (jhr@research.att.com) Date: September 17, 1992 Version: 0.89 System: n.a. Severity: major Problem: attempting to build smld produces an error Code: makeml -debug -sun4 sunos Transcript: makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.sparc mo ... [closing dbguser/hstore.sml] val it = () : unit val it = () : unit [debugging support included] structure DebugList : LIST [closing dbguser/list.sml] val it = () : unit Error: Compiler bug: DebugError:Static.locOfEvent bad APPev marking [closing dbguser/general.sml] [closing dbguser/load.sml] Comments: This works in version 0.88. Comments: [APT] I looked in and looked at this briefly. I suspect some complication due to the introduction of type options in the absyn. The correct way to diagnose this sort of problem is: 1) use makeml -debug0 to build a debugger version that doesn't attempt to execute dbguser/load.sml. 2) execute dbguser/load.sml up to the file that causes problems. 3) Set System.Control.debugging := true. Under the debugger, this will cause the absyn of the pre- and post-instrumented versions of the code to be printed. 4) Try using "dbguser/general.sml" (in this case) and look where the MARKexps come in the absyn. Compare this to what the code in debug/static.sml (where the exception was raised) is expecting. If you don't get anywhere with this, please leave the result of step 1 around in 89/bin/mipsb (I usually call it smld0) and let me know; I'll try diagnosing from here. Unfortunately, my machine is not up yet here, and telneting cross country is painfully slow... I should have a proper environment for looking at this sort of bug by early next week. Status: open ---------------------------------------------------------------------- 644. checking for stale continuations Submitter: MacQueen Date: 9/17/92 Version: 0.89 Severity: major Problem: Checking for stale continuation returns at top level has been disabled (possibly by one of Tolmach's changes to interact). Comments: See bug 145. Status: open ---------------------------------------------------------------------- 645. Compiler bug from bugs 183,228,343 code: CoreInfo.coreLty3 Submitter: Lal George Date: 9/18/92 Version: 0.90 System: Sparc, SunOS Severity: major Problem: Code for bugs 183, 228, 343 now causes "Error: Compiler bug: CoreInfo.coreLty3". Code: /usr/local/sml/testing/bugs/tests/bug183.sml, etc. Status: fixed in 0.91 (Shao) ---------------------------------------------------------------------- 646. module test tile mod14.sml fails with Compiler bug: ModuleUtil: getFctStamp Submitter: Lal George (regression testing) Date: 9/18/92 Version: 0.90a (& 0.89) Severity: major Problem: Module test case mod14.sml in /usr/local/sml/testing/hof/tests/mod14.sml fails with "Compiler bug: ModuleUtil: getFctStamp". Status: fixed in 0.90 ---------------------------------------------------------------------- 647. PWR_2_CALLEESAVE not defined in some cases Submitter: Kjeld H. Mortensen (kjeld@metasoft.com) Date: 9/22/92 Version: 0.89 System: HP9000s400 HPUX8.0 Severity: minor Problem: PWR_2_CALLEESAVE not defined in some cases, which shows up when assembling prim.s. Code: PWR_2_CALLEESAVE will not be defined when CALLEESAVE is already defined. This happens when HPUX (and M68) is defined, because makeml has a special case for this and ends up calling cpp with -DCALLEESAVE=... Transcript: Comments: Fix: If CALLEESAVE, HPUX, and M68 is defined then PWR_2_CALLEESAVE should be set to 1 because CALLEESAVE has the default value 0. I don't know if there are other cases (e.g. if -callee is used with makeml). Status: open ---------------------------------------------------------------------- 648. Compiler core dumps in the boot process for HP9000s400 HPUX8.0 Submitter: Kjeld H. Mortensen (kjeld@metasoft.com) Date: 9/22/92 Version: 0.89 System: HP9000s400 HPUX8.0 Severity: critical Problem: Compiler core dumps in the boot process Code: Transcript: Both 'makeml -m68 hpux8 -noshare' and 'makeml -m68 hpux8' results in a core dump ("Illegal instruction" or "Memory fault"). neptune 65: makeml -m68 hpux8 -noshare makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.m68 mo makeml> (cd runtime; rm -f run allmo.o allmo.s) makeml> (cd runtime; ...) makeml> /lib/cpp -DCALLEESAVE=0 -DM68 -DHPUX -DASM M68.prim.s > prim.s makeml> emacs -batch -l sun2hp.el prim.s prim.s Wrote /d1/release/tools/njsml/work89/src/runtime/prim.s makeml> as -o prim.o prim.s makeml> (cd runtime; make MACHINE=M68 'DEFS= -DHPUX' CPP=/lib/cpp 'CFL=-Wl,-a,archive' 'AS=as' 'LIBS=') cc -O -Wl,-a,archive -DM68 -DHPUX -c run.c cc -O -Wl,-a,archive -DM68 -DHPUX -c run_ml.c cc -O -Wl,-a,archive -DM68 -DHPUX -c callgc.c cc -O -Wl,-a,archive -DM68 -DHPUX -c gc.c cc -O -Wl,-a,archive -DM68 -DHPUX -c export.c cc -O -Wl,-a,archive -DM68 -DHPUX -c timers.c cc -O -Wl,-a,archive -DM68 -DHPUX -c ml_objects.c cc -O -Wl,-a,archive -DM68 -DHPUX -c cfuns.c cc -O -Wl,-a,archive -DM68 -DHPUX -c cstruct.c cc -O -Wl,-a,archive -DM68 -DHPUX -c signal.c cc -O -Wl,-a,archive -DM68 -DHPUX -c exncode.c cc -O -Wl,-a,archive -DM68 -DHPUX -c malloc.c cc -O -Wl,-a,archive -DM68 -DHPUX -c mp.c cc -O -Wl,-a,archive -DM68 -DHPUX -c sync.c cc -O -Wl,-a,archive -DM68 -DHPUX -c allmo.c "allmo.c", line 15: warning: incorrect combination of pointer and integer for operator '=' cc -O -Wl,-a,archive -DM68 -DHPUX -o run run.o run_ml.o callgc.o gc.o export.o timers.o ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o mp.o sync.o prim.o allmo.o makeml> echo ( exportML "sml"; output(std_out,System.version); output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 8192 -r 5 -h 2048 IntM68 [Increasing heap to 2048k] [Loading mo/CoreFunc.mo] [Executing mo/CoreFunc.mo] [Loading mo/Initial.mo] ... [Loading ArrayExt] [Executing ArrayExt] [Executing TypesUtil] [Loading Sort] makeml: 988 Illegal instruction - core dumped neptune 66: Comments: The compiler boots fine on a Sun3, so it doesn't have to be an MC680x0 related problem. Comments: [Kjeld] I have an additional comment: if -g is turned on in runtime/Makefile (i.e. all the runtime sources are compiled with -g and without -O), SML/NJ will boot. BUT, the compiler is flaky. It dumps a core if large integers are evaluated, and it yields compiler bug messages now and then in code that was compiled successfully on previous versions. Let me know if I can be of any help. I'm not sure what the right way is for debugging this. **** From Kjeld H. Mortensen, 11/22/92, version 0.92: I have tried to build the compiler on our HP9000s400. In order to get to the boot point I had to make the following modifications: ------------------------- diff cfuns.c.orig cfuns.c (because the gethostid call isn't known) ------------------------- 30a31,33 > #ifdef HPUX > #include <sys/utsname.h> > #endif 1432a1436,1446 > #ifdef HPUX > char buf[SNLEN+1]; > ML_val_t name; > struct utsname utsname; > > uname(&utsname); > bcopy ((char *)(utsname.idnumber), buf, SNLEN); > buf[SNLEN] = '\0'; /* insure null termination */ > name = ML_alloc_string (msp, buf); > RETURN(msp, name); > #else /* !HPUX */ 1442c1456 < --- > #endif /* HPUX */ ----------------------------- diff sun2hp.el.orig sun2hp.el (see also 564 in the masterbugs list) ----------------------------- 97,98c98 < (goto-char point) < (beginning-of-line) --- > (goto-char (- point 2)) 137a138 > (replace-re "\\.word" "short") The last change (converting .word to short) is new, and is thus not mentioned in 564. These changes allowed me to get to the boot point (i.e. all C-sources could be compiled). But then the compiler dumped a core. So, I have the following bug report: =========================================== Submitter: Kjeld H. Mortensen (kjeld@metasoft.com) Date: 11/22/92 Version: 0.92 System: HP9000s400 (M68k), HPUX 8.0 Severity: Major Problem: Compiler fails to boot. Code: Transcript: neptune 180: makeml -m68 hpux8 -noshare makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.m68 mo makeml> (cd runtime; rm -f run allmo.o allmo.s) makeml> (cd runtime; ...) makeml> /lib/cpp -DCALLEESAVE=0 -DM68 -DHPUX -DASM M68.prim.s > prim.s makeml> emacs -batch -l sun2hp.el prim.s prim.s Wrote /d1/release/tools/njsml/work92/src/runtime/prim.s makeml> as -o prim.o prim.s makeml> (cd runtime; make MACHINE=M68 'DEFS= -DHPUX' CPP=/lib/cpp 'CFL=-Wl,-a,archive' 'LDFLAGS=' 'AS=as' 'LIBS=') cc -O -Wl,-a,archive -DM68 -DHPUX -c run.c cc -O -Wl,-a,archive -DM68 -DHPUX -c run_ml.c cc -O -Wl,-a,archive -DM68 -DHPUX -c callgc.c cc -O -Wl,-a,archive -DM68 -DHPUX -c gc.c cc -O -Wl,-a,archive -DM68 -DHPUX -c export.c cc -O -Wl,-a,archive -DM68 -DHPUX -c timers.c cc -O -Wl,-a,archive -DM68 -DHPUX -c ml_objects.c cc -O -Wl,-a,archive -DM68 -DHPUX -c cfuns.c cc -O -Wl,-a,archive -DM68 -DHPUX -c cstruct.c cc -O -Wl,-a,archive -DM68 -DHPUX -c signal.c cc -O -Wl,-a,archive -DM68 -DHPUX -c exncode.c cc -O -Wl,-a,archive -DM68 -DHPUX -c malloc.c cc -O -Wl,-a,archive -DM68 -DHPUX -c mp.c cc -O -Wl,-a,archive -DM68 -DHPUX -c sync.c cc -O -Wl,-a,archive -DM68 -DHPUX -c allmo.c cc -O -Wl,-a,archive -DM68 -DHPUX -o run run.o run_ml.o callgc.o gc.o export.o timers.o ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o mp.o sync.o prim.o allmo.o makeml> echo ( exportML "sml"; output(std_out,System.version); output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 8192 -r 5 -h 2048 IntM68 [Increasing heap to 2048k] [Loading mo/CoreFunc.mo] [Executing mo/CoreFunc.mo] [Loading mo/Initial.mo] [Executing mo/Initial.mo] Initial done [Loading mo/Loader.mo] [Executing mo/Loader.mo] makeml: 3591 Memory fault - core dumped Comments: - I have been succesful building the compiler without '-noshare', but sometimes it gives a bus error when it gets to "Go for it". - The version that was successfully build with 'makeml -m68 hpux8' dumps a core when evaluating an integer that is too large: neptune 205: sml Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - 536870911; (* 2^29 - 1 *) val it = 536870911 : int - 536870912; (* 2^29 *) Illegal instruction (core dumped) - This is probably the same problem as in 648 (masterbugs). - The system builds fine on our Sun3 (also M68k) and doesn't core dump on large integers. Status: open ---------------------------------------------------------------------- 649. too strong optimization of datatype constructor (same as 642) Submitter: Pierre Cregut Date: 9/22/92 Version: 0.89 Severity: critical Problem: Printing simple datatype value causes "Compiler bug: constant datacon in decon". Code: datatype dt = a of int | b of unit; (* a is necessary *) b (); Transcript: datatype dt con a : int -> dt con b : unit -> dt val it = b Error: Compiler bug: constant datacon in decon Another version is that a piece of code is not executed if it is an argument of such a constructor. ---------------------------------------------------- - (b (print "aa\n") ; ()); val it = () : unit Comment: That is what happened in sourcegroup. To make connections, sourcegroup parse the file The toplevel rule is of type unit so a constructor " interdec of unit " is associated (interdec is the name of the rule). Because of the too strong optimization, the body of the rule that updates the tables by side effect is never executed, so source group never hears about the structures contained in the files it looks at. Status: fixed in 0.91 (Shao) ---------------------------------------------------------------------- 650. Real.realfloor has wrong type Submitter: John Reppy Date: 9/27/92 Version: 0.90 Severity: minor Problem: Isn't realfloor supposed to have type real -> real? Transcript: Standard ML of New Jersey, Version 0.90 September 22, 1992 val it = () : unit - Real.realfloor; val it = fn : 'a -> 'b Fix: obvious Status: fixed in 0.91 ---------------------------------------------------------------------- 651. System.Directory.cd fails on numbers as directory names Submitter: Konrad Slind Date: 9/28/92 Version: 0.90 System: MIPS/RISCos 4.52 Severity: major Problem: System.Directory.cd doesn't seem to recognize numbers as possible directory names: Transcript: $ mkdir 7 $ sml Standard ML of New Jersey, Version 0.90 September 22, 1992 val it = () : unit - System.Directory.cd "7"; uncaught exception NotDirectory - Status: fixed in 0.91 ---------------------------------------------------------------------- 652. Compiler bug: contmap enterv 123 building HOL Submitter: elsa elsa@research.att.com Date: 28 September Version: 90, 91a System: MIPS & SPARC, UNIX Severity: critical Problem: compiler quits with Compiler bug: contmap enterv 123 Comment: [Elsa Gunter, 9/29/92] I spent some time last night removing the HOL code from the example. Below is a mimimal example that causes the problem. Along my descent I found that the process of elimination was VERY NON-monotonic. At some time during the elimination process I had if true then 2 else 2 which could note be replaced by 2 without the bug going away. However, after removing some other aspects, the if_then_else was no longer necessary. At some point, the length of the string in the exception being handled made a difference, but now it only matters that there is a string. There were other fluxuations as well. I'm afraid I left them on my machine at home, but if you need them, I can try to bring them in tomorrow. This is very possibly not the only minimal code that causes this bug. I found that exceptions A and B must be different, that the one being handled needed to take a record with at least one field having string type and that that field had have a match against a string, i.e., not a wild-card. Code: (* File: bug-652.sml *) exception A exception B of int*string val _ = (raise A) handle B (_,"") => 2 (* end of file *) Transcript: shadow% sml Standard ML of New Jersey, Version 0.90 September 22, 1992 val it = () : unit - use "bug-652.sml"; Error: Compiler bug: contmap enterv 123 [closing bug-652.sml] - exception A; exception A - exception B of int*string; exception B - val _ = (raise A) handle B (_,"") => 2; Error: Compiler bug: CoreInfo.coreLty3 Another variation of the bug, still present in 91b: Code: (* File: bug.sml *)` structure C = struct exception A exception B of int * string val C = (raise A) handle B (_,"") => 2 end Transcript: hunny% sml Standard ML of New Jersey, Version 0.91a, October 1, 1992 val it = () : unit - use "bug.sml"; Error: Compiler bug: contmap enterv 123 [closing bug.sml] - Another variation: (from Sheard at ogi) - exception foo; - fun bar x = raise foo; Error: Compiler bug: CoreInfo.coreLty3 Comments: This is a variation on bug 652. If you unwrap the code from within the structure then things work. However it still bombs if the code is all inside a structure. Comments: Konrad says that the problem was in 88 as well. Comments: [Zhong Shao, 10/6/92] The compiler bug: contmap enterv 123 has been there for a long long time. Though previously, it occurs as a compiler bug: MipsCM.select: bad dst. These are caused by meaningless cps expressions such as SELECT(INT 0,1,v,...) , APP(INT 0, ...) which are produced by the constant folding optimization on data constructors and exception constructors. A short but temporary fix is to let contmap.sml not check the validity of these expressions and let each target code generator generate some code for SELECT(INT 0,1,v,...). Ideally this should be fixed by letting the SELECT in Lambda and CPS depend on the auxiliary variable generated in each branch and switch statement, and controlling the constant-folding on SELECT. Status: open ---------------------------------------------------------------------- 653. VECTOR signature isn't pervasive (unlike ARRAY) Submitter: Cliff Krumvieda (cliff@cs.cornell.edu) Date: September 30, 1992 Version: 0.90 System: all Severity: minor Problem: VECTOR signature isn't pervasive (unlike ARRAY) Code: Transcript: Standard ML of New Jersey, Version 0.90 September 22, 1992 val it = () : unit - signature A = ARRAY; signature A = sig type 'a array exception Size exception Subscript val array : int * '1a -> '1a array val arrayoflist : '1a list -> '1a array val length : 'a array -> int val sub : 'a array * int -> 'a val tabulate : int * (int -> '1a) -> '1a array val update : 'a array * int * 'a -> unit end - signature V = VECTOR; std_in:3.15-3.20 Error: VECTOR undefined (parser) std_in:3.15-3.20 Error: unbound signature: VECTOR Comments: Fix: add VECTOR to boot environment Status: fixed in 0.91 ---------------------------------------------------------------------- 654. System.Directory.cd fails on valid pathnames (same as 651) Submitter: Elsa L. Gunter, elsa@resaerch.att.com Date: 1 October 1992 Version: 90 (although I haven't tried earlier) System: Sparc, SunOS (although I haven't tried others) Severity: major Problem: strings from execute don't mix with System.Directory.cd (or not all strings are ccreated equal) Code: The following can cause problems when loaded with use, but more reliably causes problems when entered interactively, or so I've found. fun strip_newline (str) = substring (str, 0, size(str) - 1); fun cwd () = strip_newline (input_line ((fn (x,_) => x) (execute ("/bin/pwd",[])))); val src_dir = cwd (); val tmp = "/base/elsa/working/hol92/hol90.v5/src"; val t = (tmp = src_dir); val _ = System.Directory.cd src_dir; val _ = System.Directory.cd tmp; val _ = System.Directory.cd (src_dir ^ "/.."); val _ = System.Directory.cd src_dir; Transcript: tiree% sml Standard ML of New Jersey, Version 0.90 September 22, 1992 val it = () : unit - fun strip_newline (str) = substring (str, 0, size(str) - 1); val strip_newline = fn : string -> string - fun cwd () = strip_newline (input_line ((fn (x,_) => x) (execute ("/bin/pwd",[])))); = val cwd = fn : unit -> string - val src_dir = cwd (); val src_dir = "/base/elsa/working/hol92/hol90.v5/src" : string - val tmp = "/base/elsa/working/hol92/hol90.v5/src"; val tmp = "/base/elsa/working/hol92/hol90.v5/src" : string - val t = (tmp = src_dir); val t = true : bool - val _ = System.Directory.cd src_dir; uncaught exception NotDirectory - val _ = System.Directory.cd tmp; - val _ = System.Directory.cd (src_dir ^ "/.."); - val _ = System.Directory.cd src_dir; uncaught exception NotDirectory - Comments: -- The problem is intermittent; the same code seems to behave differently on the same machine under similar circumstances. -- Strings that are entered by hand, or are built by sml processes, such as concatenation seem not to cause the problem. Only strings created by execute (and input_line) seem to cause it. -- I haven't been able to reproduce it just now, but it I recollect that multiple executions of the same coomand (namely System.Directory.cd src_dir; without src_dir being rebound in between) could succeed for a while and then fail. Fix: add "\000" to pathnames Status: fixed in 0.91 ---------------------------------------------------------------------- 655. Compiling Isabelle-92 generates a bus error Submitter: Lal George Date: 4 Oct. '92 Version: 0.88, 0.91a (0.89, 0.90 expose the CoreLty3 bug) System: SPARC and MIPSEB Severity: critical Problem: Generates a bus error(coredump) during compilation. Code: I haven't tried to narrow the code down yet, however, at Bell Labs the following is sufficient to expose the bug: cd /usr/local/sml/isabelle-92/92/Pure Under SML: app use ["NJ.ML","ROOT.ML"]; Transcript: <... lots of stuff deleted ...> structure Earley : PARSER structure TypeExt : TYPE_EXT structure SExtension : SEXTENSION structure Pretty : PRETTY structure Printer : PRINTER Bus error(coredump) Code: [dbm, 10/10/92: following causes bus error in 91a] structure A = struct end; signature S = sig local open A in (* this must be present *) val x : unit (* must have second value beside f, either before or after *) val f: unit -> unit end end; structure B : S = (* must be constrained by S *) struct val x = () fun f() = () end; val _ = B.f(); (* causes Bus error *) Comment: [dbm] It's clear that the bug is called by the local spec form. Status: open ---------------------------------------------------------------------- 656. Excessive dead code Submitter: Lal George Date: 5th October, 92 Version: 0.90 System: SPARC Severity: major Problem: Lot of dead code left around. Code: structure X = struct (* fold function "f" over the sublists of "(x::xs)" of size "n", starting with value "r", and appending "p" to each sublist *) fun folds_onto([],_,r,p,f) = r | folds_onto(x::xs,1,r,p,f) = folds_onto(xs,1,f(r,x::p),p,f) | folds_onto(x::xs,n,r,p,f) = folds_onto(xs,n, folds_onto(xs,n-1,r,x::p,f), p,f) val l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] val n = 10 fun doit() = folds_onto(l,n,0,[],fn (total,l) => total+length(l)) end Transcript: Toggling the Control.saveLvarNames, and CG.printit flags, a partial output from cpsopt is shown below: (arrows point to dead code) ... folds_onto12224(12238,n12239,r12240,p12241,f12242,12124) = if boxed(12238) [12135] then 12238.0 -> x12136 12238.1 -> xs12137 if ineq((I)1,n12239) [12169] then 12150(12226) = --> {xs12137,n12239,12226,p12241,f12242} -> 12152 folds_onto12224(xs12137,n12239,12226,p12241,f12242,12124) -(n12239,(I)1) -> 12153 {x12136,p12241} -> 12154 --> {xs12137,12153,r12240,12154,f12242} -> 12155 folds_onto12224(xs12137,12153,r12240,12154,f12242,12150) else 12164(12228) = --> {xs12137,(I)1,12228,p12241,f12242} -> 12166 folds_onto12224(xs12137,(I)1,12228,p12241,f12242,12124) {x12136,p12241} -> 12167 {r12240,12167} -> 12168 f12242(12168,12164) else 12124(r12240) {(I)20,(I)0} -> 12174 {(I)19,12174} -> 12175 {(I)18,12175} -> 12176 ... Comment: I know that several rounds of contract are done on this fragment, and the dead code exists after each round. For some mysterious reason, code in cps/contract, that should remove this, does not seem to work. Andrew Says: This is because System.Control.CG.reducemore is 15, which causes cpsopt to give up early when it sees diminishing returns. For documentation that this is a good idea, see Compiling with Continuations, figure 15.11, page 192. Status: not a bug. ---------------------------------------------------------------------- 657. vector values not prettyprinted Date: Oct 12, 1992 Version: 0.91c System: all Severity: minor Problem: new pretty printing code doesn't handle vectors Code: Transcript: Standard ML of New Jersey, Version 0.90 September 22, 1992 val it = () : unit - #[1,2,3]; val it = #[1,2,3] : int vector Standard ML of New Jersey, Version 0.91c, October 12, 1992 val it = () : unit - #[1,2,3]; val it = prim? : int vector Status: fixed in 0.92 ---------------------------------------------------------------------- 658. Compiler bug: PrintVal.switch: none of the datacons matched Submitter: John Reppy Date: 10/13/92 Version: 0.91c System: SPARC 2, SunOS 4.0.1 Severity: critical Problem: Compiler bug: PrintVal.switch: none of the datacons matched caused by Format.compileFormat Transcript: - Format.compileFormat "x = %d"; Error: Compiler bug: PrintVal.switch: none of the datacons matched Status: fixed in 0.91 ---------------------------------------------------------------------- 659. uncaught exception SpillFreemap in closure profiling Submitter: Zhong Shao Date: October 12, 1992 Version: from 0.86 - 0.90 System: mips Severity: minor Problem: uncaught exception SpillFreemap in closure profiling Code: (* bug.sml *) structure S = struct val a = fn x => x val b = fn x => x val c = fn x => x val d = fn x => x val e = fn x => x val f = fn x => x val g = fn x => x val h = fn x => x val i = fn x => x val j = fn x => x end Transcript: haven% sml Standard ML of New Jersey, Version 0.90 September 22, 1992 val it = () : unit - System.Control.CG.allocprof := true; val it = () : unit - use "bug.sml"; [closing src/bug.sml] uncaught exception SpillFreemap - Comments: in cps/spill.sml, the instrumenting code for profiling spill records are inserted at the wrong place. Status: fixed in 0.91 ---------------------------------------------------------------------- 660. signals in background sml Submitter: Doug McIlroy (doug@research.att.com) Date: October 22, 1992 Version: 0.90 System: all Severity: major for non-interactive programs Problem: the inherited signal handler state of the SML process is getting trashed. This means that an SML program running in the background still receives signals, even though the shell has disabled them. Fix: The fix will take a bit of work, since the responsibility for signal handling is spread throughout the system. We will have to make the signal handler state (enabled, default, ignored) more visible at the System.Signals level, and the top-level loop and other initialization code will have to check for ignored signals when setting the default handlers. (JHR) Status: open ---------------------------------------------------------------------- 661. prettyprinter -- Compiler bug: PPTable.install_pp Submitter: Lal George Date: 28 October 1992 Version: 0.91 System: all Severity: minor Problem: install_pp incorrectly raises a compiler bug message Code: val _ = System.PrettyPrint.install_pp ["foo","bar"] Array.update Transcript: Error: unbound structure foo in path foo.bar Error: Compiler bug: PPTable.install_pp Comments: The first error message is also printed with an additional blank space. Fix: In file print/pptable and function install_pp, replace: | _ => ErrorMsg.impossible "PPTable.install_pp" with | _ => ErrorMsg.complain "install_pp: Malformed path" May as well do the same thing with fun make_path. [dbm] Used ErrorMsg.errorNoFile for this and make_path -- no more calls of ErrorMsg.impossible in pptable.sml. Status: fixed in 0.92 (dbm) ---------------------------------------------------------------------- 662. delayed interrupt on MIPS Submitter: Dave MacQueen Date: 10/28/92 Version: 0.91 System: MIPS/RISCOS 4.52 Severity: minor Problem: Typing the interrupt character (e.g. ^C) doesn't interrupt sml until after a newline is typed. Comments: This could be fixed, but the piping into sml would hang under csh. This is really a RISCos bug. Status: not our bug ---------------------------------------------------------------------- 663. gc loop on illegal character Submitter: Lal George Date: 10/28/92 Version: 0.91 System: SPARC, MIPS Severity: major Problem: Typing an illegal character (e.g. ^H) at top level causes an infinite gc loop after the illegal character message. Fix: [Lal George] The fix is to generate ml.lex.sml with a version of lexgen.sml that has the latest bug fixes. The one on /usr/local/sml/bin/sparc does fine. Status: fixed in 0.92a ---------------------------------------------------------------------- 664. installing on Sony RISC NEWS Submitter: KONO Shinji <kono@csl.sony.co.jp> Date: Wed Nov 4 17:34:01 JST 1992 Version: 0.75 System: Sony RISC NEWS, NEWS-OS Release 4.1R Severity: minor Problem: Installation Code: makeml -mips news Transcript: EXC_OV and cache clear system call are machine dependent Comments: I'm afraid this type of mahcine is not famous in U.S. But I'm sure it is used in Japan... Fix: Diffs are appended.. -------- Shinji Kono kono@csl.sony.jp Sony Computer Science Laboratory, Inc. diff -c ./makeml /site/unicorn/export/src/Language/sml-0.75/src/makeml *** ./makeml Wed Nov 4 15:35:55 1992 --- /site/unicorn/export/src/Language/sml-0.75/src/makeml Tue Sep 8 09:55:11 1992 *************** *** 129,135 **** ENDIAN=Big case $1 in riscos) OPSYS=RISCos; CFL="$CFL -systype bsd43" ;; - news) OPSYS=BSD;; mach) OPSYS=MACH; DEFS="$DEFS -DBSD" ;; *) echo "$CMD must specify opsys arg for MIPS (riscos or mach)" --- 129,134 ---- *** runtime/MIPS.dep.c Wed Nov 4 16:28:06 1992 --- /site/unicorn/export/src/Language/sml-0.75/src/runtime/MIPS.dep.c Tue Sep 8 09:54:00 1992 *************** *** 5,18 **** * MIPS dependent code for SML/NJ runtime kernel. */ - #ifdef sony_news - #include <machine/cpu.h> /* for EXC_OV */ - #else #ifndef SGI #include <mips/cpu.h> /* for EXC_OV */ #else #include <sys/sbd.h> /* for EXC_OV */ - #endif #endif #ifndef SGI #include <syscall.h> --- 5,14 ---- diff -c runtime/exncode.c /site/unicorn/export/src/Language/sml-0.75/src/runtime/exncode.c *** runtime/exncode.c Wed Nov 4 16:27:33 1992 --- /site/unicorn/export/src/Language/sml-0.75/src/runtime/exncode.c Tue Sep 8 09:54:03 1992 *************** *** 6,19 **** */ #ifdef MIPS - #ifdef sony_news - #include <machine/cpu.h> /* for EXC_OV */ - #else #ifndef SGI #include <mips/cpu.h> /* for EXC_OV */ #else #include <sys/sbd.h> /* for EXC_OV */ - #endif #endif #endif #include <signal.h> --- 6,15 ---- diff -c runtime/ml_os.h /site/unicorn/export/src/Language/sml-0.75/src/runtime/ml_os.h *** runtime/ml_os.h Wed Nov 4 16:47:12 1992 --- /site/unicorn/export/src/Language/sml-0.75/src/runtime/ml_os.h Tue Sep 8 09:54:05 1992 *************** *** 94,106 **** /* cache-flushing stuff */ #if defined(MIPS) - #ifdef sony_news - #include <machine/sysnews.h> - # define FlushICache(addr, size) \ - sysnews(NEWS_CACHEFLUSH, addr, size, FLUSH_ICACHE) - /* SYS_sysnews will be defined in syscall.h, in OS 4.1 */ - #undef SYS_sysnews - #else #ifndef MACH #include <sys/sysmips.h> #endif --- 94,99 ---- *************** *** 117,122 **** --- 110,116 ---- # define FlushICache(addr, size) \ (syscall(SYS_sysmips, MIPS_CACHEFLUSH, (addr), (size), ICACHE, 0)) # endif + #else #ifdef NeXT # define FlushICache(addr, size) asm ("trap #2") #else *************** *** 123,129 **** # define FlushICache(addr, size) #endif #endif - #endif #if defined(MACH) && defined(MIPS) --- 117,122 ---- *************** *** 139,145 **** #endif /* where to find syscall.h, used for getting the #define SYS_open */ ! #if defined(VAX) || defined(NeXT) || defined(MORE) || defined(sony_news) #include <syscall.h> #else #ifndef SGI --- 132,138 ---- #endif /* where to find syscall.h, used for getting the #define SYS_open */ ! #if defined(VAX) || defined(NeXT) || defined(MORE) #include <syscall.h> #else #ifndef SGI Status: open ---------------------------------------------------------------------- 665. Compiler bug: getSymbols on opening nonexistent structures. Submitter: Pierre Cregut Date: 11/5/92 Version: 0.91, 0.92a Severity: minor Problem: Compiler bug: getSymbols on opening nonexistent structures. Transcript: Standard ML of New Jersey, Version 0.92a, November 2, 1992 val it = () : unit - open A; std_in:2.1-2.6 Error: unbound structure A Error: Compiler bug: getSymbols Fix: add ERROR_STR case to getSymbols function in elabstr.sml. Status: fixed in 0.92 (dbm) ---------------------------------------------------------------------- 666. top-level printout on open declarations Submitter: John Reppy Date: 11/6/92 Version: 0.91 Severity: minor Problem: When opening a structure, the bound datatypes don't get printed. Transcript: - structure Foo = struct datatype t = A | B val x = A end; structure Foo : sig datatype t con A : t con B : t val x : t end - open Foo; open Foo val x = A : t - Comments: In fact, only dynamic components are printed, since only they are rebound in the top-level environment (to simplify stale-lvars cleanup). Fix: Change printing of open declarations? Status: open ---------------------------------------------------------------------- 667. Compiler bug: getvars(STRdec)/fn opening a structure Submitter: Thomas Yan, tyan@cs.cornell.edu Date: 11/10/92 Version: 0.91 Severity: minor, but potentially very annoying Problem: ? pretty printing a structure created by functor application ? Code: functor A(type aa) = struct type a = aa list val a =[] end structure A = A(type aa = int) open A Transcript: Error: Compiler bug: getvars(STRdec)/fn Fix: ignore special name "<Argument>" in elabDecl/makeDecl. Status: fixed in 0.92 (dbm) ----------------------------------------------------------------------- 668. missing info in syntax error messages Submitter: Lal George Date: 11/13/92 Version: 0.92c Severity: major Problem: Some information has been lost from syntax error messages. Transcript: (bug103.sml) {999} -----------------------diff new old ---------------------- diff tsml.tmp /usr/local/sml/testing/bugs/outputs/bug103.out 2,3c2 < std_in:8.5 Error: syntax error < --- > std_in:8.5 Error: syntax error found at RBRACE Comments: The "found at" part of the message is missing from the new mlyacc/base.sml supplied by Tarditi. Fix: This was a non-error-correcting version of base.sml that was inadvertently left in the mlyacc directory sent by Tarditi. The fix was to build and install the error-correcting version of base.sml. Status: fixed in 0.92c ---------------------------------------------------------------------- 669. redundant rule added in some matches Submitter: Dave MacQueen Date: 11/16/92 Version: 0.92c Severity: major Problem: A rule is added to raise the match exception (and save a location message) in cases where it is redundant. Code: Transcript: - fun f(s,w) = f s w; std_in:0.0-0.0 Error: pattern and expression in val rec dec don't agree (circularity) pattern: 'Z -> 'Y -> 'X expression: 'Z * 'Y -> 'X in declaration: f = (fn (s,w) => <exp> <exp> w | _ => (<exp> := <exp>; raise <exp>)) <==== redundent rule Fix: Caused by switch to prettyprinter for absyn. Left out call of trim to trim last default rule when printing match in CASEexp and FNexp. Status: fixed in 0.92 (dbm) ---------------------------------------------------------------------- 670. missing indicators in redundant match warning messages Submitter: Dave MacQueen Date: 11/16/92 Version: 0.88 through 0.92c Severity: major Problem: In version 0.87 and earlier an arrow "-->" was printed in front of redundant rules in the warning message for redundant matches. Code: (in file bug670.sml) fun f (true,x) = 0 | f (true,nil) = 1 | f (false, x) = 2 | f w = 3; Transcript: Standard ML of New Jersey, Version 0.87, July 31, 1992 val it = () : unit - use "bug670.sml"; bug670.sml:1.1-4.11 Warning: redundant patterns in match (true,x) => ... --> (true,nil) => ... (false,x) => ... --> w => ... val f = fn : bool * 'a list -> int Standard ML of New Jersey, Version 0.92b, November 11, 1992 val it = () : unit - use "bug670.sml"; [opening bug670.sml] bug670.sml:1.1-4.11 Warning: redundant patterns in match (true,x) => ... (true,nil) => ... (false,x) => ... w => ... val f = fn : bool * 'a list -> int Comments: I think that 0.88 was the version that incorporated Bill Aitken's rewrite of the match compiler, so it is probably caused by that change. Fix: added a rev around call of fixupUnused in doMatchCompile in translate/mc.sml. fixupUnused was returning a list of ints sorted in the wrong order. Status: fixed in 0.92 (dbm) ---------------------------------------------------------------------- 671. visibility of parameter in functor signature Submitter: Zhong Shao (zsh@cs.princeton.edu) Date: Nov. 17, 1992 Version: 0.91 System: all Severity: major Problem: unbound structure in functor signature definitions Code: (* case 1 *) funsig FSIG(B : sig type t end) = sig val f : B.t end (* case 2 *) funsig FSIG(structure B : sig type t end) = sig val f : B.t end (* case 3 *) funsig FSIG(B : sig type t end) = sig val f : t end (* case 4 *) funsig FSIG(structure B : sig type t end) = sig val f : t end Transcript: haven% sml Standard ML of New Jersey, Version 0.91, October 26, 1992 val it = () : unit - funsig FSIG(B : sig type t end) = sig val f : B.t end; std_in:2.47-2.49 Error: unbound structure B in path B.t - funsig FSIG(structure B : sig type t end) = sig val f : B.t end; std_in:0.0-0.0 Error: unbound structure B in path B.t - funsig FSIG(B : sig type t end) = sig val f : t end; funsig FSIG(B:<sig>) = sig val f : <Argument>.<Parameter>.t end - funsig FSIG(structure B : sig type t end) = sig val f : t end; std_in:2.57 Error: unbound type constructor t Comments: The code for case 1 and 2 should be valid, as they are in 89. The code for case 3 and 4 should be rejected (intuitively) Fix: Here is the fix for the bug in signatures of functors: tulipe-cregut->diff elabsig.sml elabsig.sml~ 539,540c539,540 < of (NONE,_) => Normalize.openX(name_X,sgnArg,symtotalParent) < | (SOME _ ,_) => --- > of (SOME _,_) => Normalize.openX(name_X,sgnArg,symtotalParent) > | (NONE,_) => It is just a stupid inversion... Status: fixed in 0.93 ---------------------------------------------------------------------- 672. start() in i386 Mach Submitter: Mark Leone (mleone@cs.cmu.edu) Date: 11/18/92 Version: 0.91 System: i386 Mach Severity: minor Problem: start() is now _start() in i386 Mach. Comments: I386.prim.s used to require an #ifdef for Mach to set startptr to start(), not _start(). This is no longer necessary. Fix: *** I386.prim.s.orig Wed Nov 18 13:25:23 1992 --- I386.prim.s Wed Nov 18 13:24:13 1992 *************** *** 651,658 **** /* this bogosity is for export.c */ .globl _startptr _startptr: - #if defined(I386) && defined(MACH) - .long _start - #else .long start - #endif --- 651,654 ---- Status: fixed in 0.92 ---------------------------------------------------------------------- 673. failure of type propagation with higher-order functors Submitter: Dave MacQueen Date: 11/20/92 Version: 0.92 Severity: major Problem: Type information is not propagated through application of a parameter functor. Code: (bug673.sml) signature MONOID = sig type t val plus: t*t -> t val e: t end; (* functor signature declaration *) funsig PROD (structure M: MONOID structure N: MONOID) = MONOID functor Square(structure X: MONOID functor Prod: PROD): MONOID = Prod(structure M = X structure N = X); functor Prod(structure M: MONOID structure N: MONOID): MONOID = struct type t = M.t * N.t val e = (M.e, N.e) fun plus((m1,n1),(m2,n2))=(M.plus(m1,m2),N.plus(n1,n2)) end; structure Int = struct type t = int val e = 0 val plus = (op +): int*int -> int end; structure Int2 = Square( structure X = Int functor Prod = Prod); #1(Int2.e); Transcript: Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - use "bug673.sml"; [opening bug673.sml] signature MONOID = sig type t val plus : t * t -> t val e : t end funsig PROD(<Parameter>:<sig>) = sig type t val plus : t * t -> t val e : t end functor Square : <sig> functor Prod : <sig> structure Int : sig eqtype t val e : int val plus : int * int -> int end structure Int2 : MONOID bug673.sml:39.1-39.10 Error: operator and operand don't agree (type mismatch) operator domain: {1:'Y, '...Z} operand: Int2.t in expression: (fn {1=1,...} => 1) (e) [closing bug673.sml] - Fix: [Cregut] diff elaborate/elabstr.sml elaborate/elabstr.sml~ 525,528c525,528 < fun computeSelf (StructStr _) = true < | computeSelf (MarkStr(def,_,_)) = computeSelf def < | computeSelf _ = false < val self = computeSelf def --- > val self = > (case def of VarStr _ => false > | MarkStr(VarStr _,_,_) => false > | _ => true) Ok I think it fixes the problem: match thought that it could suppress its origin whereas it was a computed application to be done at each functor application. In the bogus version you could correct the problem - by suppressing the signature MONOID - by putting an intermediate level of structure so that the optimisation of self was irrelevant (which is a kind of bug but we have already talked about it) (an intermediate level = functor Square(,,,) = struct structure result = Prod(...) end; ) Status: fixed in 0.93 ---------------------------------------------------------------------- 674. System.Env.filterEnv raises exception IntmapF Submitter: Dave MacQueen Date: 11/22/92 Version: 0.92 Severity: major Problem: System.Env.filterEnv raises exception IntmapF. Transcript: - System.Env.filterEnv(!System.Env.pervasiveEnvRef,[System.Symbol.valSymbol "hd"]); uncaught exception IntmapF Comments: Probably related to bug 640. Fix: fix lvarOfBinding in modules/moduleutil.sml Status: fixed in 0.93a (dbm) ---------------------------------------------------------------------- 675. prettyprinter doesn't sense System.Print.linewidth Submitter: Konrad Slind Date: 11/23/92 Version: 0.92 Severity: major Problem: System.Print.linewidth doesn't seem to control the linewidth used by the system prettyprinter. Transcript: $ sml Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - System.Print.printLength := 10000; val it = () : unit - val L = ["adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa"]; val L = ["adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd", "afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa", "adsfasd","afasdfa","adsfasd","afasdfa"] : string list - System.Print.linewidth := 20; val it = () : unit - L; val it = ["adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd", "afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa", "adsfasd","afasdfa","adsfasd","afasdfa"] : string list - System.Print.linewidth := 150; val it = () : unit - L; val it = ["adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd", "afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa", "adsfasd","afasdfa","adsfasd","afasdfa"] : string list - Status: open ---------------------------------------------------------------------- 676. Out of order record field evaluation. Submitter: Andrew Appel Date: 11/24/92 Version: 0.92 Severity: Critical Problem: Out of order record field evaluation. Transcript: Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - val r = ref 0; val r = ref 0 : int ref - fun g() = (inc r; !r); val g = fn : unit -> int - {last=g(),first=g()}; val it = {first=1,last=2} : {first:int, last:int} Status: fixed in 0.93 (Zhong Shao) ---------------------------------------------------------------------- 677. memory leak Submitter: Kjeld H. Mortensen (kjeld@metasoft.com) Date: 11/24/92 Version: 0.92 Systems: Sparc server 330, SunOS 4.1.1, HP9000s400, HPUX 8.0 Severity: Major Problem: Memory leaks (heap grown when not supposed to). Code: Transcript: Comments: I have made experiments with SML/NJ v0.92 in order to see if there were any memory leaks. It seems to me that it is the case. My standard experiment is the same as from bug report #500, which was fixed by v0.82. The bug was present in v0.75 and now in v0.92, but not to the same degree. I've included a bug report in case you think it should be added to the masterbugs list. It is very important for us that the compiler doesn't slow down over a longer period of usage, as a result of memory leaks. So I've given the bug a high priority. Using the compiler over a long period of time where stuff is only evaluated or values "overwritten", the heap size increases unnecessarely (see also bug #500). (v0.92) ----------Mem Size---------- start end end-start ratio softmax slow down Sparc 19968 kb 21096 kb 1128 kb 3 28 Mb 26 % HPs400 11224 kb 11900 kb 676 kb 3 32 Mb 16 % The table shows memory usage (as show by 'ps') at the beginning and end of the experiment, the difference between end and start, ratio and softmax (from System.Control.Runtime), and how much slower the compiler is at the end as compared with the beginning of the experiment. The session lasts 45 and 60 minutes for the HP and Sparc respectively. I want to point out that the earlier version 0.82 doesn't have any detectable memory leak and therefore no slow down. Status: fixed in 0.93c ---------------------------------------------------------------------- 678. emacs tags broken Submitter: Charlie Krasic (cckrasic@plg.uwaterloo.ca) Date: Nov. 24/92 Version: 0.92 System: Sun 670/MP (Sparc) w/SunOS 4.3 (?) Severity: minor Problem: emacs tags broken when trying to create TAGS file for SML/NJ Code: modified the file 'all' to contain directives to toggle indexing and markabsyn, then run smlc < all, then run sml-tags -r. I tried both my old version of sml-tags and a newly built version of sml-tags. Transcript: no transcript. Re-compiling the entire system creates the various .i.xxx tag files. Running "sml-tags -r" gives: uncaught exception getIntError Comments: This precedure works fine if I use a batch compiler based on 0.91 Status: open ---------------------------------------------------------------------- 679. "Compiler bug: addObject" while compiling the Edinburgh library Submitter: wkh@dce.austin.ibm.com (Ward K. Harold) Date: 11/25/92 Version: 0.92 (works up through version 0.82, fails in version 0.83) System: RS6000, AIX 3.2, MIPS, SPARC Severity: major Problem: "Compiler bug: addObject" while compiling the Edinburgh library, version 1.20 or 1.21. Occurs when loading MonoSet.sml in the MonoSet functor. Code: (* simplified version: bug679.sml *) functor F (X: sig end) = (* has to be a functor, not a structure *) struct abstype s = S with type t = unit (* type definition necessary *) end end Transcript: Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - use "foo.sml"; [opening foo.sml] Error: Compiler bug: addObject [closing foo.sml] - Fix: [Pierre Cregut] When I counted the number of components created in a structure that have a representation in the core, I forgot to count the components coming from the body of an abstype tulipe-cregut->diff elabstr.sml elabstr.sml~ 42,44c42,43 < | (AbstypeDec {abstycs,withtycs,body,...}, t) => < let val (strN,fctN,typN) = count (body,t) < in (strN,fctN,typN+length abstycs+length withtycs) end --- > | (AbstypeDec {abstycs,withtycs,...}, (strN,fctN,typN)) => > (strN,fctN,typN + length abstycs + length withtycs) Status: fixed in 0.93 ---------------------------------------------------------------------- 680. Bad vertical alignment prettyprinting case expression. Submitter: Dave MacQueen Date: 11/20/92 Version: 0.92 Severity: minor Problem: Bad veritcal allignment prettyprinting case expression. Transcript: - if 2 then 3 else 4; std_in:0.0-0.0 Error: case object and rules don't agree (tycon mismatch) rule domain: bool object: int in expression: (case 2 of true => 3 | false => 4) Status: fixed in 0.93c ---------------------------------------------------------------------- 681. building on SGI Indigos with cc version 3.10 Submitter: asgeir@viking.asd.sgi.com (Asgeir Eiriksson), Fernando Pereira Date: 12/2/92 Version: 0.92 System: SGI R3000 and R4000 Indigo Severity: Major Problem: sml fails to build with /usr/bin/cc version 3.10 (the latest) Transcript: cc -O -DMIPS -D_BSD_SIGNALS -D__STDC__ -Dsgi -DSGI -o run run.o run_ml.o callgc.o gc.o export.o timers.o ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o mp.o sync.o prim.o allmo.o /usr/bin/ld: This executable contains branch instruction(s) at end-of-page makeml> echo ( exportML "sml"; output(std_out,System.version); output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 8192 -r 5 -h 2048 IntMipsBig [Increasing heap to 2051k] [Loading mo/CoreFunc.mo] ... [closing boot/perv.sml] [Loading boot/overloads.sml] structure Overloads : ... [closing boot/overloads.sml] Go for it - [Major collection... 15% used (550960/3548736), 350 msec] [Decreasing heap to 2699k] [Major collection... 100% used (552208/552208), 320 msec] ==> Inconsistent object for export: !(0) uncaught exception Io "exportML "sml": Error 0" - Comments: This does not occur with the 2.10 version of cc. Reproducible on Fernando Pereira's Indigo. Status: fixed in 0.93 ---------------------------------------------------------------------- 682. excess newlines in compiler warning message Submitter: Thomas Yan tyan@cs.cornell.edu Date: 12/2/92 Version: .92 Severity: minor Problem: extraneous blank lines printed during compilation Code: val [1,2,3] = [1,2,3] Transcript: - val [1,2,3] = [1,2,3]; std_in:55.1-55.21 Warning: binding not exhaustive 1 :: 2 :: 3 :: nil = ... - Comments: baffling the first time it appears Fix: In print/ppdec.sml, make each declaration responsible for printing it's own terminating newline. Status: fixed in 0.93c ---------------------------------------------------------------------- 683. Compiler bug: Extern: update_structure 2 Submitter: Sanjiva Prasad <sanjiva@ecrc.de> Date: 12/2/92 Version: 0.92 Severity: minor Problem: Elaborating an illegal signature decl leads to Compiler bug: Extern: update_structure 2. Code: signature S = sig functor Foo(X: S) : S end Transcript: Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - signature S = = sig = functor Foo(X: S) : S = end; std_in:4.18 Error: unbound signature: S std_in:4.23 Error: unbound signature: S Error: Compiler bug: Extern: update_structure 2 Fix: [Pierre Cregut] update_structure didn't consider the case where an error had already been encountered. I have added two cases: the structure is an error, the signature is an error. Only the second one is proved to be necessary but the first one is safe. tulipe-cregut->diff extern.sml extern.sml~ 102,103d101 < | ERROR_STR => () < | INSTANCE{sign as ERROR_SIG,...} => () Status: fixed in 0.93 ---------------------------------------------------------------------- 684. Compiler bug: checkList Submitter: Sanjiva Prasad <sanjiva@ecrc.de> Date: 12/2/92 Version: 0.92 Severity: major Problem: A functor definition causes "Compiler bug: checkList". Transcript: - signature S1 = sig end; signature S1 = sig end - funsig FOO (X:S1) (Y:S1) = S1; funsig FOO(X:<sig>) = sig functor <functor> : <sig> end - structure A:S1 = struct end; structure A : S1 - functor Bar (C:S1) = C; functor Bar : <sig> - functor Foo (X:S1) (Y:S1) = X; functor Foo : <sig> - functor Foo:FOO = Foo; functor Foo : <sig> - funsig FOO2 (X:S1) = S1; funsig FOO2(X:<sig>) = sig end - functor Dummy (W: sig functor F :FOO2) (functor Z:FOO2) = Z(A); std_in:9.38 Error: syntax error found at RPAREN - functor Dummy (W: sig functor F :FOO2 end ) (functor Z:FOO2) = Z(A); functor Dummy : <sig> - functor Bar1 = Dummy (Foo(A)) (functor Z = Bar); std_in:10.16-10.47 Error: unmatched structure spec: F std_in:10.16-10.47 Error: unbound functor: <functor> in path <hidden>.<functor> - functor Dummy (W: S1) (functor Z:FOO2) = Z(A); functor Dummy : <sig> - functor Bar1 = Dummy (Foo(A)) (functor Z = Bar); std_in:11.16-11.47 Error: unbound functor: <functor> in path <hidden>.<functor> - structure C:S1 = struct functor G=Bar end; structure C : S1 - open C; open C - structure C:S1 = Foo(A); structure C : S1 - open C; open C - funsig ARBIT (B:S1) (type t) = S1; funsig ARBIT(B:<sig>) = sig functor <functor> : <sig> end - - - functor Bar5 = Foo (Foo A); std_in:18.25 Error: syntax error found at ID - functor Bar5 = Foo (Foo (A) ); Error: Compiler bug: checkList Code: (* bug684.sml *) (* the following reproduces the bug in 0.92 *) signature S = sig end; funsig FOO (X:S) (Y:S) = S; functor Foo (X:S) (Y:S) = X; functor Foo: FOO = Foo; (* with this deleted produces different strange error *) structure A:S = struct end; structure C:S = Foo(A); (* with this deleted, no error *) functor Bar5 = Foo(Foo(A)); (* ===> Error: Compiler bug: checkList *) Comments: Currently one must view all arguments to a functor as structures. In particular, if an argument to a H-O functor is itself a functor, it is viewed as being a functor component of a structure argument. But suddenly here, I found some funny behaviour when trying to treat results of part-applying curried functors as structures. I've attached the session transcript. The symptoms were repeated when I replayed the session script in toto. But when I tried to redo things with some of the chaff (irrelevant definitions and evaluations) removed, things worked fine. The Compiler bug checkList was a surprise. Status: fixed in 0.93 (probably same as 673) ---------------------------------------------------------------------- 685. loss of line numbers loading with System.Compile Submitter: Gene Rollins Date: 12/3/92 Version: 0.92 Severity: minor Problem: Code loaded into the interactive system using System.Compile does not give accurate line numbers when using System.Compile rather than use. Code: structure c :sig val c :string -> unit end = struct open System.Env System.Compile fun withSource (sourceName:string) (action :source -> 'a -> 'b) (argument:'a) :'b = let val sourceStream = open_in sourceName val source = makeSource (sourceName, 1, sourceStream, false, {linewidth= !System.Print.linewidth, flush=System.Print.flush, consumer=System.Print.say}) val result = action source argument handle exn => (closeSource source; raise exn) in closeSource source; result end fun c (sourceName:string) :unit = let val env = layerEnv (!topLevelEnvRef, !pervasiveEnvRef) val se = staticPart env fun comp source () = compile (source, se) val compUnit = withSource sourceName comp () in () end end ********** a.sml ******* structure a = struct fun f [] = () end ************************ See the difference with: - c.c "a.sml"; - use "a.sml"; Fix: In elaborate/frontend.sml, make parse smash linePos only for interactive source. Also fixed it so that compileAst can take an optional source parameter so linenumbers can be provided in error messages for elaborating and translating asts. (build/compile.sml, boot/system.sig) Status: fixed in 0.93c ---------------------------------------------------------------------- 686. floating-point divide by zero is broken on SGI Submitter: D. A. Ladd (ladd@graceland.ih.att.com) Date: November 30, 1992 Version: 0.91, 0.92 System: SGI Severity: major Problem: floating-point divide by zero is broken Code: 1.0 / 0.0; Transcript: Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - 1.0 / 0.0; strange floating point error, 14 Comments: This works okay on other MIPS-based machines (e.g., hunny). Status: fixed in 0.93 ---------------------------------------------------------------------- 687. src/Makefile is out of date. Submitter: Fernando Pereira Date: 12/4/92 Version: 0.92 Severity: major Problem: src/Makefile is out of date. First of all, the Makefile refers to ../tools/sourcegroup but the distribution has SG2.2nj. With this fixed, various files seem to be missing: cat ../tools/gnutags/export.sml | sml-export Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit [opening ../tools/sourcegroup/src/StringXtra.sig] [use failed: open_in "../tools/sourcegroup/src/StringXtra.sig": openf failed, No such file or directory] uncaught exception (Loader): SystemCall Then sml-conn fails to make because ../tools/sourcegroup/sml-conn/export.sml is missing. Finally, sourcegroups fail to build with [opening date.sml] [use failed: open_in "date.sml": openf failed, No such file or directory] [closing ../tools/sourcegroup/save.sml] uncaught exception (Loader): SystemCall Comments: the files required to build smlsg and sml-conn are all there so they can be built manually. (sml-conn/export.sml no longer exists). Fix: get rid of src/Makefile Status: fixed in 0.93 (check) ---------------------------------------------------------------------- 688. profiler doesn't compile Submitter: Fernando Pereira Date: 12/5/92 Version: 0.92 Severity: major Problem: Building the profiling version of sml fails while compiling profile/profperv.sml when executing sml < profile/script Transcript: [opening profile/profperv.sml] val it = () : unit profile/profperv.sml:73.17-73.26 Error: operator is not a function operator: bytearray in expression: ba sub profile/profperv.sml:79.18-79.32 Error: operator and operand don't agree (tycon mismatch) operator domain: bytearray operand: (bytearray * int -> int) -> int -> 'Z in expression: length ba profile/profperv.sml:83.16-83.33 Error: operator and operand don't agree (tycon mismatch) operator domain: bytearray operand: (bytearray * int -> int) -> int -> 'Z in expression: length ba profile/profperv.sml:88.29-88.41 Error: operator is not a function operator: bytearray in expression: ba sub [closing profile/profperv.sml] Fix: add "infix 9 sub" just after "open ByteArray", because infixes are no longer carried by structures (signatures?). [ByteArray shouldn't be signature constrained because of inlining!!!] Status: fixed in 0.93a ---------------------------------------------------------------------- 689. Compiling lambda prolog fails with compiler bug "adjust_variable". Submitter: Fernando Pereira Date: 12/5/92 Version: 0.92 Severity: Critical Problem: Compiling lambda prolog fails with compiler bug "adjust_variable". Code: elp.tar.Z Transcript: sgiharrar:lp$ sml-export Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - use "export-elp.sml"; .... lots of stuff .... [opening elp/elp_global_program.fun] elp/elp_global_program.fun:23.34-23.70 Error: operator and operand don't agree (type mismatch) operator domain: '2Z * '2Y operand: '2Z * '2Y in expression: ref (imports,program) elp/elp_global_program.fun:23.7-24.26 Error: operator and operand don't agree (type mismatch) operator domain: string * (string list * Program.program) ref operand: string * _ in expression: ModuleState (module_name,ref (imports,program)) elp/elp_global_program.fun:26.10-26.27 Error: operator and operand don't agree (type mismatch) operator domain: string * string operand: string * string in expression: = (module_name,m1) elp/elp_global_program.fun:27.12-27.38 Error: operator and operand don't agree (type mismatch) operator domain: (string list * Program.program) ref * (string list * Program.program) operand: (string list * Program.program) ref * (string list * Program.program) in expression: := (entry,(imports,program)) Error: Compiler bug: adjust_variable [closing elp/elp_global_program.fun] Status: fixed in 0.93 (probably related to bug 673 or 671) ---------------------------------------------------------------------- 690. maskSignals breaks interactive input Submitter: Andrew Tolmach apt@cs.pdx.edu Date: 12/8/92 Version: 0.92 System: Sun4 SunOS, Sequent, probably others Severity: minor Problem: maskSignals breaks interactive input Code: - System.Signals.maskSignals true; - ^C Transcript: With above code, system goes into infinite loop. Comments: Any signal for which a handler is installed will do in place of CTRL/C. The problem is in cfuns.c/ml_wait_for_in: restart:; /* on EINTR */ if (msp->inSigHandler || ((! _setjmp (msp->SysCallEnv)) && (5) (((msp->ioWaitFlag = 1), (msp->NumPendingSigs == 0))))) { ... (1) select() ... } else { (6) backup_kont(msp); sigsetmask (0); /* re-enable signals */ return; } if (sts == -1) { if (errno == EINTR) (4) backup_kont(msp); else raise_syserror(msp, 0); return; } and its interaction with signal.c/sig_handler: /* record the signal */ (2) msp->NumPendingSigs++; msp->SigTbl[ml_sig]++; (3) if (!msp->maskSignals) { if (msp->ioWaitFlag) { /* We were waiting for a blocking I/O operation when the signal occurred, * so longjmp out of the operation (see io_wait() in "cfuns.c"). */ _longjmp (msp->SysCallEnv, 1); } else ... } Suppose we've called maskSignals false, setting msp->maskSignals to true, have called ml_wait_for_in, and are sitting in the select call (line 1) when a signal occurs. The following occurs: 1) The system invokes sig_handler, which increments NumPendingSigs (line 2) but doesn't longjmp out because of the test at line 3. 2) The select call returns EINTR, so ml_wait_for_in calls backup_kont (line 4) to set up the ML state to reenter C immediately. 3) When ml_wait_for_in is reentered, it refuses to recall select because of the test on NumPendingSignals at line 5; instead, it calls backup_kont again (line 6), and returns to C. This step is then repeated forever. Fix: One possiblity is to change the test in line 5 to: (5) (((msp->ioWaitFlag = 1), (msp->NumPendingSigs == 0 || msp->maskSignals))))) { Or, the position of the test against maskSignals could be changed in sigHandler, so that the longjmp is always activated? In that case, EINTR should never be returned, right? Comment [jhr]: I've thought about this, and I think that the correct fix is to check for masked signals in ml_wait_for_in (also in ml_select). In particular. the code should be if (msp->inSigHandler || msp->maskSignals || ...) since being in a signal handler implies masked signals. I would point out that calling maskSignals prior to calling ml_in_wait is bogus, since the whole point of ml_in_wait is to provide a safe place to interrupt when waiting for input. Status: fixed in 0.93 ---------------------------------------------------------------------- 691. Compiler bug: ModuleUtil: lookFormalBinding 1 Submitter: Pierre Cregut Date: 12/8/92 Version: 0.92 Severity: Major Problem: Compiler bug: ModuleUtil: lookFormalBinding 1 Code: signature S1 = sig type a ; val intro : unit -> a end; functor F4 (structure X1 : S1) (structure X2 : sig val x : X1.a end) = struct end; Comments: But I am afraid there are other changes to make. The bug comes from FULL_SIG found while elaborating the argument of an embedded functor. There are other places where FULL_SIG are created. I will try to eliminate all of them. Fix: Here is a fix: tulipe-cregut->diff elabstr.sml elabstr.sml~ 352,355c352 < binding = < STR_FORMAL{ < pos=0, < spec=signatureOfStructure argument}, --- > binding = STR_FORMAL{pos=0,spec=FULL_SIG}, Status: fixed in 0.93 ---------------------------------------------------------------------- 692. signal handling on 386 can dump core Submitter: Andrew Tolmach apt@cs.pdx.edu Date: 12/14/92 Version: 0.90+ System: visible on Sequent; affects all 386 systems Severity: critical Problem: signal handling on 386 can dump core Code: open System.Signals fun alarmHandler(_,k) = k val _ = setHandler(SIGALRM,SOME(alarmHandler)) open System.Timer val setitimer = System.Unsafe.Cinterface.setitimer fun h() = setitimer(0,TIME{sec=0,usec=10000} TIME{sec=0,usec=10000}); (* System can dump core at any time after h() is executed. The following sequence is quite reliable on Sequents: *) val cd = System.Directory.cd; fun r() = let fun f () = (cd "."; f()) in h(); f() end; r(); Comments: The problem is that limitptr lives on the stack and is addressed relative to %esp. Unfortunately, various operations in the 386 implemention (notably saveregs, some fp operations, and all pc-relative loads in generated code) temporarily push things onto the stack, thus altering %esp. But the adjust_limit routine, which zeroes the limitptr, may be executed by command of the signal handler *at any time* when inML == 1; thus the wrong piece of the "ML stack frame" gets zeroed (in this case the exncont). Fix: Add a field MLframe to the ML state vector (for 386's only), pointing to the base of the ML stack frame. This field is initialized by restoreregs before setting inML = 1. The signal handler uses this pointer to access and zero the limit pointer directly, avoiding the need for an adjust_limit routine. [I've sent Lal a bundle containing these changes.] Longer-term fix: If the 386 implementation were cleaned up so that it no longer messed with %esp, use of the MLframe pointer in the signal handler could be replaced by scp->sp. Status: fixed in 0.93 ---------------------------------------------------------------------- 693. backspace (rubout char) under HPUX 8.0 Submitter: M.J.Morley <mjm@uk.ac.ed.dcs> Date: 17-12-92 Version: Version 75, November 11, 1991 System: HP 380/9000 under HP-UX 8.0 Severity: minor bur, major irritation in all ML applications Problem: Backspace incorrectly bound? Comments: This was not manifest under HP-UX 7.0 but when we recently switched to the HP-UX 8.0 the backspace `stopped working'. Characters are rubbed out but this effect is not echoed to the screen. The kit we use is the standard HP config. screen/mouse/KB -- running MIT's X11R4, in case that is significant. Status: not our bug ---------------------------------------------------------------------- 694. System.Compile.execute provokes compiler bug ModuleComp.getImport Submitter: Kjeld H. Mortensen (kjeld@metasoft.com) Date: 12/21/92 Version: 0.92 System: Sparc, SunOS 4.1.1 Severity: major Problem: System.Compile.execute provokes ModuleComp.getImport compiler bug msg Code: The file "test.sml" used in the following is just: signature FOO = sig val x : int end; structure foo = struct val x = y end; Transcript: Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - val y= 0; val y = 0 : int - val myenv= System.Env.concatEnv (!System.Env.topLevelEnvRef, !System.Env.pervasiveEnvRef); val myenv = prim? : environment - val mystatenv= System.Env.staticPart myenv; val mystatenv = prim? : staticEnv - val myppcons= {linewidth= 79, consumer= (fn (x:string) => print x), flush= (fn () => ())}; val myppcons = {consumer=fn,flush=fn,linewidth=79} : {consumer:string -> unit, flush:unit -> unit, linewidth:int} - val mystream= open_in "test.sml"; (* See 'Code' above *) val mystream = - : instream - val mysrc = System.Compile.makeSource ("test.sml", 1, mystream, false, myppcons); val mysrc = prim? : source - val myStatxCode= System.Compile.compile (mysrc, mystatenv); val myStatxCode = ({boundLvars=[10162],staticEnv=prim?},prim?) : System.Compile.staticUnit * codeUnit - val mynewenv= System.Compile.execute (myStatxCode, myenv); Error: Compiler bug: ModuleComp.getImport uncaught exception Compile Comment: [dbm] Free value variables in compilation units are not supported in 0.93. This problem will go away in 0.94. Status: not a bug ---------------------------------------------------------------------- 695. segmentation fault involving System.Ast Submitter: Gene Rollins Date: 12/22/92 Version: 0.92 System: Decstation, Mach Severity: critical Problem: segmentation fault Code: structure bug = struct structure A = System.Ast fun ok m = (print ("\n<OK "^m^">\n"); flush_out std_out) val p1 = "functor G = H" val p2 = "functor F () = struct end" fun try program = let val ppc = {linewidth = !System.Print.linewidth, flush = System.Print.flush, consumer = System.Print.say} val strm = open_string (program ^ "\n") val src = System.Compile.makeSource ("", 1, strm, false, ppc) val start = System.Env.staticPart (!System.Env.pervasiveEnvRef) val (ast, se) = System.Compile.parse (src, start) in do_dec ast handle exn => (close_in strm; raise exn); close_in strm end and do_dec (ast:A.dec) :unit = (case ast of (A.ValDec _) => () | (A.ValrecDec _) => () | (A.FunDec _) => () | (A.TypeDec _) => () | (A.DatatypeDec _) => () | (A.AbstypeDec _) => () | (A.ExceptionDec _) => () | (A.StrDec _) => () | (A.AbsDec _) => () | (A.FctDec (arg:A.fctb list)) => app f_fctb arg | (A.SigDec _) => () | (A.FsigDec _) => () | (A.LocalDec _) => () | (A.SeqDec arg) => app do_dec arg | (A.OpenDec _) => () | (A.OvldDec arg) => () | (A.FixDec arg) => () | (A.ImportDec arg) => () | (A.MarkDec (arg,_,_)) => do_dec arg ) and f_fctb (ast:A.fctb) :unit = (case ast of (A.Fctb {name:symbol, def:A.fctexp}) => f_fctexp def | (A.MarkFctb (arg,_,_)) => f_fctb arg ) and f_fctexp (ast:A.fctexp) :unit = let val _ = ok "0" in case ast of (A.VarFct (path:A.path, constraint:A.fsigexp option)) => let val _ = ok "1" val symbol'list = ((System.Unsafe.cast path) :symbol list) in case path of [] => ok "1a" | (head::tail) => (ok "1b"; System.Symbol.name head; ok "1c") end | (A.FctFct {params :(symbol option * A.sigexp) list, body :A.strexp, constraint :A.sigexp option}) => ok "2" | (A.MarkFct (arg,_,_)) => (ok "3"; f_fctexp arg) end end Transcript: - bug.try bug.p1; (* ok *) - bug.try bug.p2; (* causes segmentation fault *) Comments: If you look at the output, it seems that in the function f_fctexp, the case on the ast should go on the FctFct branch for bug.p2, but it goes on the VarFct branch. When I try to bind the offending ast to a name at the top-level I get: Error: Compiler bug: PPVal.switch: none of the datacons matched Fix: eternalized ast did not agree with internal ast on type fctexp. Status: fixed in 0.93c (dbm) ---------------------------------------------------------------------- 696. Type system error in "includes" of signatures Submitter: Chet Murthy (murthy@margaux.inria.fr) Date: 29 Dec 1992 Version: 0.92 System: sun4, sunos 4.1 Severity: major Problem: Type system error in "includes" of signatures Code: see transcript Transcript: I just found a bug in signature mechanism of 0.93. It manifests itself when I construct signatures by using "include". I enclose a short file which elicits the bug in the version of 0.93 which I recuperated from research.att.com, around the end of november. P.S. The result of the bug is a bus error. --------------cut here------------------- structure A = struct type (''1a, '1b) t = ((''1a * '1b) list) fun new() = nil fun toList l = l fun dom (l:(''a, 'b) t) = List.map #1 l end signature ASIG = sig type (''1a, '1b) t val new : unit -> (''1a, '1b) t end signature BSIG = sig type (''1a, '1b) t val dom : (''1a, '1b) t -> ''1a list end ; signature AB_SIG = sig include ASIG BSIG end ; structure goo : AB_SIG = A; let val _ = goo.dom (SOME "foo") in 23 end; Fix [Cregut]: tulipe-cregut->diff elabsig.sml elabsig.sml~ 68c68 < fun adjustBinding (basetype,basestr,basefct,baseslot,makeStamp,redef) = --- > fun adjustBinding (basetype,basestr,basefct,baseslot,makeStamp) = 108,112d107 < and relocate pos = < let fun reloc [] = pos+basetype < | reloc ((porig,pdest)::l) = < if pos = porig then pdest else reloc l < in reloc redef end 125c120 < FORMtyc{pos=relocate pos, --- > FORMtyc{pos=pos+basetype, 143c138 < RELtyc {name=name,pos=([],relocate offset)} --- > RELtyc {name=name,pos=([],offset+basetype)} 181c176 < val adjust = adjustBinding (!tycons,!strs,!fcts,!slots,makeStamp,redef) --- > val adjust = adjustBinding (!tycons,!strs,!fcts,!slots,makeStamp) Status: fixed in 0.93c ---------------------------------------------------------------------- 697. wrong Subscript exception in ByteArray Submitter: Chet Murthy (murthy@margaux.inria.fr) Date: 12/29/92 Version: 0.92 System: Sun4, rel 4.1 Severity: minor Problem: ByteArray.sub and ByteArray.update raise Array.Subscript and not ByteArray.Subscript (otherwise named Ord) Code: let val x = ByteArray.array(10,0) in ByteArray.sub(x,11) end Transcript: Comments: Fix: In translate/inlineops.sml - the change was two one-liners, to make "sub" and "update" return CoreInfo.exnOrd, instead of CoreInfo.exnSubscript in inlstore and inlbyteof. I enclose the patch at the end. *** inlineops.sml.~1~ Wed Nov 18 00:06:10 1992 --- inlineops.sml Sat Dec 26 18:18:20 1992 *************** *** 123,129 **** COND(APP(PRIM(P.LESSU,predTy), RECORD[vi,APP(PRIM(P.LENGTH,lengthTy),vs)]), APP(PRIM(P.ORDOF,ordofty),RECORD[vs,vi]), ! RAISE(conToLexp(!CoreInfo.exnSubscript),INTty))))) end (* Bytearray store: --- 123,129 ---- COND(APP(PRIM(P.LESSU,predTy), RECORD[vi,APP(PRIM(P.LENGTH,lengthTy),vs)]), APP(PRIM(P.ORDOF,ordofty),RECORD[vs,vi]), ! RAISE(conToLexp(!CoreInfo.exnOrd),INTty))))) end (* Bytearray store: *************** *** 154,160 **** COND(APP(PRIM(P.LESSU,predTy),RECORD[vc,INT 256]), APP(PRIM(P.STORE,storety),RECORD[vs,vi,vc]), RAISE(conToLexp(!CoreInfo.exnRange),INTty)), ! RAISE(conToLexp(!CoreInfo.exnSubscript),INTty)))))) end (* String ordof: --- 154,160 ---- COND(APP(PRIM(P.LESSU,predTy),RECORD[vc,INT 256]), APP(PRIM(P.STORE,storety),RECORD[vs,vi,vc]), RAISE(conToLexp(!CoreInfo.exnRange),INTty)), ! RAISE(conToLexp(!CoreInfo.exnOrd),INTty)))))) end (* String ordof: Status: fixed in 0.93c (dbm) ---------------------------------------------------------------------- 698. Uninformative nonexhaustive match warning messages. Submitter: John Reppy Date: 12/29/92 Version: 0.92 System: Sparcstation Severity: major Problem: Uninformative nonexhaustive match warning messages. Transcript: When compiling Isabelle/Pure: lexicon.ML:63.9-63.73 Warning: match nonexhaustive <pat> => ... lexicon.ML:55.9-61.62 Warning: match nonexhaustive <pat> => ... <pat> => ... <pat> => ... Comments: Looks like printdepth is set to low, but doesn't happen at top level. [appel: Isabelle actively resets the print depth, and brings this problem upon itself.] Status: not a bug ---------------------------------------------------------------------- 699. "Compiler bug: ModuleUtil: lookFormalBinding 1" (secondary) Submitter: John Reppy Date: 12/31/92 Version: 0.93b Severity: minor Problem: "Compiler bug: ModuleUtil: lookFormalBinding 1" generated as secondary error message after an unbound signature reference. Code: (contents of file trace-cml.sml) functor TraceCML ( structure CML : INTERNAL_CML and RunCML : RUN_CML and CIO : CIO (* <== should have been signature CONCUR_IO *) sharing CML = RunCML.CML = CIO.CML ) : TRACE_CML = struct structure CIO = CIO (* where to direct trace output to *) datatype trace_to = TraceToOut | TraceToErr | TraceToNull | TraceToFile of string | TraceToStream of CIO.outstream end; (* TraceCML *) Code: (simplified) functor F(structure A : sig end structure B : SXX (* undefined sig SXX *) sharing A = B.C) = (* undefined component B.C -- error msg *) struct end Transcript: [opening trace-cml.sml] trace-cml.sml:13.14-13.16 Error: unbound signature: CIO Error: Compiler bug: ModuleUtil: lookFormalBinding 1 [closing trace-cml.sml] Fix: added a case: | STRbind(STRvar{binding=STR_FORMAL{spec=ERROR_SIG,...},...}) => raise ErrorStructure in function lookFormalBinding in modules/moduleutil.sml. Status: fixed in 0.93c ---------------------------------------------------------------------- 700. wrong printing with toplevel vector pattern Submitter: Dave MacQueen Date: 1/3/93 Version: 0.93b Severity: minor Problem: Top level does not print value bindings when a vector pattern is used. Transcript: Standard ML of New Jersey, Version 0.93b, December 14, 1992 val it = () : unit - val #[x,y,z] = #[1,2,3,]; std_in:2.1-2.23 Warning: binding not exhaustive #[x,y,z] = ... - - val [x,y] = [3,4]; std_in:0.0-0.0 Warning: binding not exhaustive x :: y :: nil = ... val x = 3 : int val y = 4 : int - Comment: Note also the extra newlines for the printing of the list bindings. Status: fixed in 0.93c ---------------------------------------------------------------------- 701. wrong types printed for top-level exception declarations Submitter: Andrzej Filinski <andrzej@cs.cmu.edu> Date: January 12, 1993 Version: 0.92 (November 18, 1992) System: all Severity: minor Problem: wrong types printed for top-level exception declarations Transcript: Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - exception E; exception E [ok] - exception E of int; exception E [same for all non-functional types] - exception E of int->bool; exception E of int [only codomain reported for functional types] Fix: changed print/ppdec.sml Status: fixed in 0.93c ---------------------------------------------------------------------- 702. realfloor is unimplemented Submitter: Thomas Yan, tyan@cs.cornell.edu Date: 1/12/93 Version: .75, .92 (so presumably ever since .75) Severity: major Problem: realfloor is unimplemented Comments: hard to work around -- need to know/compute internal representation of floats Suggestion: [appel] local val maxint = 4503599627370496.0 (* This is the IEEE double-precision maxint; won't work accurately on VAX *) fun realround x = if x>=0.0 then x+maxint-maxint else x-maxint+maxint (* realround(x) returns x rounded to some nearby integer, almost always the nearest integer. *) in fun realfloor x = let val y = realround x in if y>x then y-1.0 else y end end Status: open ---------------------------------------------------------------------- 703. betaexpand in cpsopt goes into infinite loop Submitter: Greg Morrisett Date: 13 Jan 1993 Version: 0.92 System: Mips Mach, Sparc Mach, (probably all) Severity: critical Problem: betaexpand in cpsopt goes into infinite loop Code: val rec f = fn true => f false | false => f true Transcript: Standard ML of New Jersey, Version 0.92, November 18, 1992 val it = () : unit - val rec f = fn true => f false | false => f true; [Major collection... [Increasing heap to 2741k] [Increasing heap to 2941k] [Increasing heap to 3941k] [Increasing heap to 7001k] 95% used (2120604/2211028), 2078 msec] <killed> Comments: Don't be fooled by the fact that this code doesn't terminate. The original code that I whittled down to this *did* terminate. It was a slight modification of cps/contract.sml. Let me know if you want the original code... Comment: [Greg, 1/18/93] I'm not so sure that the problem is just in betaexpand, now. The example code I gave you compiles if you turn betaexpand off, but my real code only compiles if you turn off all of cpsopt. Comment: (awa) Compilation of his original (large) program did not infinite loop! It merely kept going for approximately 14^6 beta-expansions, which took a long time and a lot of space. [understatement] Fix: [temporary. awa, 1/19/93] System.Control.CG.unroll := false; [permanent, awa, 1/20/93] Add "andalso n < max" to UNROLL case in body of function should_expand in cps/expand.sml. Also, let max=2, not max=5 (which was excessive) Status: fixed in 0.93c (awa) ---------------------------------------------------------------------- 704. System.Unsafe.SysIO.access raises exception instead of returning false Submitter: John Reppy (jhr@research.att.com) Date: January 14, 1993 Version: 0.93 (and earlier) System: all Severity: minor Problem: System.Unsafe.SysIO.access raises an exception when its argument is inaccessable, instead of returning false. Code: System.Unsafe.SysIO.access ("some-file-that-does-not-exist", []); Transcript: Standard ML of New Jersey, Version 0.93a, December 9, 1992 val it = () : unit - System.Unsafe.SysIO.access ("some-file-that-does-not-exist", []); uncaught exception SystemCall Comments: In the long run, there should be a datatype for the return value of access, since it can fail for significantly different reasons (e.g., no such file, not a directory, looping path, ...). Fix: Change the code in cfuns.c to return false instead of raising SystemError Status: fixed in 0.93 ---------------------------------------------------------------------- 705. sml emacs subprocess dies when file is "used" Submitter: David Ladd (ladd@research.att.com) Date: 1/21/92 Version: 0.93a System: SGI, R3000, IRIX 4.0.4 Severity: major Problem: The following file works fine if ``used'' from the shell prompt, but dies when ``used'' under emacs. Code: (file bug705.sml) exception foo; fun foo'(x) = raise foo; foo'(4); Transcripe: Standard ML of New Jersey, Version 0.93a, December 9, 1992 val it = () : unit - [opening /tmp/t] exception foo val foo' = fn : 'a -> 'b [closing /tmp/t] uncaught exception foo uncaught exception (Loader): SystemCall Process cmusml finished Status: open (can't reproduce) ---------------------------------------------------------------------- 706. non-terminating structure compilation Submitter: Knut Omang (Univ. of Oslo), knuto@ifi.uio.no Date: Fri Jan 8 , 1993 Version: 0.75 System: ds & sun4 (the below run done on a Sun Sparcstation 2) Severity: major Problem: non-terminating structure compilation Code: -------- structure Queue1 = struct type 'a T = 'a list; exception E; fun hd(x::q) = x | hd [] = raise E; end signature QUEUE = sig type 'a T exception E val hd : 'a T -> 'b T end; structure Q1: QUEUE = Queue1; Transcript: ------------ Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "qm.sml"; [opening qm.sml] structure Queue1 : sig eqtype 'a T exception E val hd : 'a list -> 'a end signature QUEUE = sig type 'a T exception E val hd : 'a T -> 'b T end [Major collection... [Increasing heap to 2116k] [Increasing heap to 2636k] [Increasing heap to 5236k] 97% used (1614112/1649172), 1240 msec] [Increasing heap to 8012k] [Major collection... [Increasing heap to 11916k] 95% used (4137248/4349188), 3120 msec] [Increasing heap to 12752k] ^C[closing qm.sml] Interrupt - Comments: This program should probably terminate quickly with an error msg.. Status: fixed since 0.75 ---------------------------------------------------------------------- 707. overloading in the profiler Submitter: Lal George Date: 1/21/93 Version: 0.93b Severity: major Problem: Operators do not have their normal overloaded properties in the profiler. Transcript: - kisubi:$ smlp Standard ML of New Jersey, Version 0.93b, December 14, 1992[PROFILING] val it = () : unit - fun f x = x + 1; std_in:8.11-8.15 Error: operator and operand don't agree (tycon mismatch) operator domain: real * real operand: real * int in expression: + (x,1) Status: fixed in 0.93c (lal) ---------------------------------------------------------------------- 708. array too large Submitter: Carl Gunter Date: 1/25/93 Version: 0.93b System: Sparcstation Severity: major Problem: Allocating very large array leads to strange behavior. Transcript: bolete% sml Standard ML of New Jersey, Version 0.93b, December 14, 1992 val it = () : unit - open Array; ... - val A = array(100, true); val A = [|true,true,true,true,true,true,true,true,true,true,true,true,...|] : bool array - sub(A,5); val it = true : bool But this is different: bolete% sml Standard ML of New Jersey, Version 0.93b, December 14, 1992 val it = () : unit - open Array; ... - val A = array(1073741823, true); val A = [||] : bool array - sub(A,5); val it = false : bool - sub(A, 13098); ... emacs window freezes ... Comment: the size is too large to fit in the 26 bits reserved in the descriptor; the assembly language was not checking this. Fix: Change the ML code in perv.sml to check for size before calling assembly language. Status: fixed in 0.93c ---------------------------------------------------------------------- 709. bad indentation Submitter: Dave MacQueen Date: 1/26/92 Version: 0.93c System: Mips Magnum, RISCos 4.52 Severity: minor Problem: System printout after opening a structure (System.Compile) has bad indentation. Transcript: Standard ML of New Jersey, Version 0.93b, December 14, 1992 val it = () : unit - open System.Compile; open Compile structure PP : sig type ppconsumer end structure IO : sig type instream type outstream end structure Ast : sig type dec end exception Compile = Compile val makeSource = fn : string * int * instream * bool * System.PrettyPrint.ppconsumer -> source val closeSource = fn : source -> unit val changeLvars = fn : staticUnit -> staticUnit val elaborate = fn : source * staticEnv -> staticUnit val parse = fn : source * staticEnv -> Ast.dec * staticEnv val compile = fn : source * staticEnv -> staticUnit * codeUnit val compileAst = fn : Ast.dec * staticEnv * source option -> compUnit val execute = fn : (staticUnit * codeUnit) * environment -> environment val eval_stream = fn : instream * environment -> environment val use = fn : string -> unit val use_stream = fn : instream -> unit - - Status: fixed in 0.93 ---------------------------------------------------------------------- 710. 0.0/0.0 generates strange float exception (on a NeXT) Submitter: Joel F. Klein, Joel.Klein@Rose-Hulman.EDU Date: 1/28/93 Version: 0.75 System: NeXTstation <hardware and OS version> Severity: minor Problem: 0.0/0.0 generates strange float exception (on a NeXT) Code: 0.0/0.0 Transcript: mercutio 9:50pm > sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - 0.0/0.0; strange floating point error, 0xd0 mercutio 9:52pm > Comments: This is a known and "fixed" bug, but NeXTs don't know that. Comments: [Joel Klein, 1/20/93] I have additional information on bug report 710. I left out which operating system the NeXT was running. This appears to be important, because the "normal" NeXTs around here have a different response to the same input. Here's the summary: NeXT running NeXTstep 3.0: 0.0/0.0 generates "strange float error" NeXT running NeXTstep 2.0: 0.0/0.0 returns 0.0 Example transscript of latter: - 0.0/0.0; val it = 0.0 : real [Appel:] SML/NJ 0.92 gives strange floating point error 0xd on NeXT 3.0. Status: open ---------------------------------------------------------------------- 711. SystemCall exceptions Submitter: Benli Pierce Date: 9/30/92 Version: 0.90 System: sparc Severity: major Problem: I've encountered one strange behavior while playing around with SML 0.90 on a sparc. Calls to System.system sometimes raise SystemCall exceptions -- not in a fresh sml-sg image, but after a while, when a few things have been compiled. I thought it must be a problem with running out of virtual memory, but I was able to get the same behavior after killing off several big processes. Status: open ---------------------------------------------------------------------- 712. Compiler bug: Modules.distributeT:f DD146 Submitter: Tyng-Ruey Chuang, chuang@cs.nyu.edu Date: Oct. 27, 1992 Version: 0.75 System: Sun Sparc, O.S. version 4.1.1 Severity: not major Problem: Compiler-error when local specification is used with type sharing equation in a signature declaration. Code: Note: named as "bug.sml" in Transcript. (*----------------------------------------------------------------------------*) (* Signature "FLIP" and its associated functor "Flip" *) signature FLIP = sig datatype Side = LHS | RHS end functor Flip () : FLIP = struct datatype Side = LHS | RHS (* LHS for left-hand-side and RHS for right-hand-side *) end (*----------------------------------------------------------------------------*) (* Signature "FLOP" and its associated functor "Flop". Signature "FLOP" is identical(?) to "FLIP" though their names are different. Functor "Flop" should generate a structure identical to its input structure. *) signature FLOP = sig local structure flip : FLIP in datatype Side = LHS | RHS sharing type Side = flip.Side end end functor Flop (flip : FLIP) : FLOP = struct local structure flip = flip in open flip end end (*----------------------------------------------------------------------------*) (* A test to see if the following structures are identical(?). *) structure flip = Flip () structure flop = Flop (flip) val identical = flip.LHS = flop.LHS Transcript: Script started on Tue Oct 27 17:16:00 1992 spunky% sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - use "bug.sml"; [opening bug.sml] bug.sml:24.5-24.26 Warning: LOCAL specs are only partially implemented Error: Compiler bug: Modules.distributeT:f DD146 [closing bug.sml] - ^D spunky% ^D script done on Tue Oct 27 17:16:18 1992 Comments: The bug goes away if either local specifications in signatures are removed or sharing equation is removed. For example: (*----------------------------------------------------------------------------*) (* Signature "FLIP" and its associated functor "Flip" *) signature FLIP = sig datatype Side = LHS | RHS end functor Flip () : FLIP = struct datatype Side = LHS | RHS (* LHS for left-hand-side and RHS for right-hand-side *) end (*----------------------------------------------------------------------------*) (* Signature "FLOP" and its associated functor "Flop". Signature "FLOP" is identical(?) to "FLIP" though their names are different. Functor "Flop" should generate a structure identical to its input structure. *) signature FLOP = sig structure flip : FLIP (* NO local declaration here. *) datatype Side = LHS | RHS sharing type Side = flip.Side end functor Flop (flip : FLIP) : FLOP = struct structure flip = flip (* NO local declaration here. *) open flip end (*----------------------------------------------------------------------------*) (* A test to see if the following structures are identical(?). *) structure flip = Flip () structure flop = Flop (flip) val identical = flip.LHS = flop.LHS OR (*----------------------------------------------------------------------------*) (* Signature "FLIP" and its associated functor "Flip" *) signature FLIP = sig datatype Side = LHS | RHS end functor Flip () : FLIP = struct datatype Side = LHS | RHS (* LHS for left-hand-side and RHS for right-hand-side *) end (*----------------------------------------------------------------------------*) (* Signature "FLOP" and its associated functor "Flop". Signature "FLOP" is identical(?) to "FLIP" though their names are different. Functor "Flop" should generate a structure identical to its input structure. *) signature FLOP = sig datatype Side = LHS | RHS end functor Flop (flip : FLIP) : FLOP = struct open flip end (*----------------------------------------------------------------------------*) (* A test to see if the following structures are identical(?). *) structure flip = Flip () structure flop = Flop (flip) val identical = flip.LHS = flop.LHS Status: not a bug ---------------------------------------------------------------------- 713. sourcegroups crashes in a non-deterministic fashion. Submitter: Lal George Date: 28th Oct. '92 Version: 0.91 System: RS6000 Severity: major Problem: sourcegroups crashes in a non-deterministic fashion. Code: Compile sourcegroups version 2.2. (This was brought to my attention by cliff@cs.cornell.edu) Transcript: [/usr/u/plg/SMLofNJ/91/tools/sourcegroup] bashful% sml-91 Standard ML of New Jersey, Version 0.91, October 26, 1992 val it = () : unit - use "build.sml"; [opening build.sml] val print'sigs = 2 : int val it = () : unit [opening load-all.sml] [opening local/System/interrupt.sig] signature INTERRUPT = ... [closing local/System/interrupt.sig] val it = () : unit [opening local/System/interrupt.sml] structure Interrupt : INTERRUPT [closing local/System/interrupt.sml] val it = () : unit [opening local/System/ioStream.sig] signature IO_STREAM = ... [closing local/System/ioStream.sig] val it = () : unit [opening local/System/ioStream.sml] structure IO_Stream : IO_STREAM [closing local/System/ioStream.sml] val it = () : unit [opening tools/sepcomp.sml] [Major collection... [Increasing heap to 2719k] [Increasing heap to 2979k] 33% used (729592/2187412), 200 msec] [Increasing heap to 3643k] signature SEPCOMP = ... structure SepComp : SEPCOMP [closing tools/sepcomp.sml] val it = () : unit [opening tools/compile.sml] signature COMPILE = ... structure Compile : COMPILE [closing tools/compile.sml] val it = () : unit val it = () : unit val load = fn : string -> unit [reading base.sml] [Major collection... [Increasing heap to 3711k] [Increasing heap to 4051k] 32% used (955024/2984028), 310 msec] [Increasing heap to 4743k] [Major collection... 17% used (697240/3897980), 230 msec] [closing base.sml] val it = () : unit [reading local/System/pathname.sig] [closing local/System/pathname.sig] val it = () : unit [reading local/System/ioStream.sig] [closing local/System/ioStream.sig] Illegal instruction ====================================================================== Fix: The bug is caused by the lack of cache flushing after code generation. Add the line System.Unsafe.CInterface.flush_cache <string> wherever appropriate. Status: fixed in 0.93 ---------------------------------------------------------------------- 714. failure of ByteArray.update Submitter: Fred Sullivan (sullivan@cs.rose-hulman.edu) Date: 11/2/92 Version: 0.75 System: NeXT and Sun 3/SunOS Severity: major Problem: ByteArry.update seems to fail in the following circumstances: 1. System.Control.interp is false. 2. update is called at top level. Transcript: Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - open ByteArray; open ByteArray - val a = array(5, 65); val a = - : bytearray - extract (a, 0, 5); val it = "AAAAA" : string - update (a, 3, 66); val it = () : unit - extract (a, 0, 5); val it = "AAAAA" : string - update (a, 0, 67); val it = () : unit - extract (a, 0, 5); val it = "\000AAAA" : string - If update is not called at top level, it seems to work: - fun foo (a, m, n) = update (a, m, n); val foo = fn : bytearray * int * int -> unit - foo(a, 0, 67); val it = () : unit - extract (a, 0, 5); val it = "CAAAA" : string - Status: fixed in 0.93 ---------------------------------------------------------------------- 715. chdir often doesn't work on strings of length 0 mod 4 Submitter: Andrew Tolmach (apt@cs.pdx.edu) Date: 6 Nov 92 Version: 0.90 (and perhaps earlier versions) System: all Severity: minor Problem: chdir often doesn't work on strings of length 0 mod 4 Code: System.Unsafe.CInterface.chdir "abcd"; (* this directory does exist *) Transcript: % sml Standard ML of New Jersey, Version 0.90 September 22, 1992 val it = () : unit - System.Unsafe.CInterface.chdir "abcd"; (* this directory does exist *) uncaught exception SysError - Comments: Caused by failure to call c_string on argument to chdir in boot/perv.sml. String seen by C may have arbitrary garbage after it. Fix: Replace val chdir : string -> unit = c_function "chdir" by val chdir : string -> unit = c_function "chdir" o c_string in boot/perv.sml. Status: fixed in 0.93 ---------------------------------------------------------------------- 716. overflow on real operation crashes sml on sparc Submitter: Masahiro YASUGI < yasugi@is.s.u-tokyo.ac.jp > Date: Tue Nov 17 16:18:27 JST 1992 Version: Standard ML of New Jersey, Version 75, November 11, 1991 System: Sun4/SunOS Release 4.1.1-JLE1.1.1RevB Severity: rare Problem: An overflow on real number in sequential execution causes a crash of sml. Code: fun bug r = ( r * r; r:real ); bug 1.0E160; or fun bug r = ( r /0.0; r ); bug 1.0; Transcript: % sml Standard ML of New Jersey, Version 75, November 11, 1991 Arrays have changed; see Release Notes val it = () : unit - fun bug r = ( r /0.0 ; r :real ); val bug = fn : real -> real - bug 1.0; Segmentation fault % Comments: It seems to be a lower-level problem. Status: open ---------------------------------------------------------------------- 717. records always evaluated in alphabetical order Submitter: Thomas Yan, tyan@cs.cornell.edu Date: 12/10/92 Version: 0.92 Severity: major Problem: records always evaluated in alphabetical order Code: val _ = {b= print "1", a = print "2"} Transcript: - val _ = {b= print "1", a = print "2"}; 21 - Comments: aren't records supposed to be evaluated in the order they appear in program text? Status: fixed in 0.93 ---------------------------------------------------------------------- 718. accepts type incorrect program, crashes Submitter: Norman Neff neff@trenton.edu Date: 1/26/93 Version: 0.75 System: Sun SPARC 1+ Sun OS 4.1.1 Severity: critical Problem: compiler accepts type-incorrect program, execution nonterminates Code: <example code that reproduces the problem> (* binary arithmetic *) val max'digits=100; structure Bins (*: sig exception add'oflow exception doub'oflow exception expadd'oflow exception btr'oflow exception btd'oflow val add'2 : ByteArray.bytearray * ByteArray.bytearray -> ByteArray.bytearray val subtract'2 : ByteArray.bytearray * ByteArray.bytearray -> ByteArray.bytearray val binary'to'int : ByteArray.bytearray -> int val is'zero : ByteArray.bytearray -> bool val binary'to'real : ByteArray.bytearray -> real val int'to'binary : int -> ByteArray.bytearray val real'to'binary : real -> ByteArray.bytearray val expadd : int * ByteArray.bytearray -> ByteArray.bytearray